J'ai un building_table et api :: building_table, j'aimerais avoir les données de building_table par défaut mais si les données n'existent pas dans building_table j'aimerais avoir à les obtenir à api :: building_table. Le problème est qu'il existe des attributs qui n'existent peut-être pas dans building_table mais qui existent dans api building_table. Il y a aussi des colonnes qui ont un nom différent dans chaque table.
Voici mon exemple de code
def get_building_info building = Building.find_by(id: params[:id]) api_building = Api::Building.find_by(id: params[:id]) building_hash = {} building_hash[:name] = building.name || api_building.name building_hash[:room] = building.room || api_building.room building_hash[:rent] = building.rent || api_building.monthly_fee ... end
y a-t-il une manière plus élégante de faire cela? btw ceci est dans mon contrôleur.
5 Réponses :
Il existe de nombreuses solutions pour y parvenir, mais voici une solution plus simple:
def get_building_info building = Hash.new building[:name], building[:room] = desired_building.name, desired_building.room end private def desired_building Building.find_by(id: params[:id]) || Api::Building.find_by(id: params[:id]) end
Le problème est qu'un certain attribut peut être extrait de la construction de l'API, mais cela ne signifie pas que d'autres attributs seront également extraits de la construction de l'API.
Vous n'avez pas eu de question sur OP
Je pense que vous le faites d'une manière correcte mais la variable building
sera écrasée, vous devez définir une nouvelle variable comme
building2 = {}
Vous n'avez pas eu de question sur OP
Je suis désolé de l'avoir tapé dans le navigateur et c'était une faute de frappe!
before_action :find_records, only: :get_building_info def get_building_info building_hash = {} building_hash[:name] = building_name building_hash[:room] = building_room # OR building_hash[:name], building_hash[:room] = building_name, building_room end private def find_records @building = Building.find_by(id: params[:id]) @api_building = Api::Building.find_by(id: params[:id]) end def building_name @building.name || @api_building.name end def building_room @building.room || @api_building.room end
salut, merci pour la réponse. Mon modèle de bâtiment est composé de 12 colonnes de plus, pensez-vous que c'est une bonne pratique d'en avoir 12 en privé?
Non ce n'est pas ,. je pensais que vous n'aviez que 2 paramètres
Pourquoi pas? Vous pouvez facilement les générer tous, donc il faudrait 5 lignes pour les 12 méthodes.
@AlekseiMatiushkin mais 12 méthodes privées, je pense que votre solution est bien meilleure que la mienne.
L'approche générique, acceptant la liste des clés comme argument:
def get_building_info(keys = %i[name room rent].zip(%i[name room fee])) building = Building.find_by(id: params[:id]) api_building = Api::Building.find_by(id: params[:id]) keys.map do |key, api_key| [ key, building.attributes[key.to_s] || api_building.attributes[api_key.to_s] ] end.to_h end
ma question semble manquer de plus de détails, je suis désolé!
J'ai aussi pensé à cela mais j'ai des colonnes de table qui ont des noms différents. Je suis désolé de ne pas l'avoir inclus dans ma question!
Mise à jour d'une réponse.
la raison pour laquelle je n'accepte pas les paramètres pour get_building_info est parce que c'est une requête ajax donc je n'ai id comme paramètre pour la construction.
Je ne suis pas sûr de suivre. La méthode ci-dessus fait exactement ce que vous voulez et peut parfaitement être appelée sans aucun paramètre passé. Comme vous pouvez le voir, il a une valeur par défaut pour l'argument.
Je pense que c'est très élégant, mais que se passe-t-il s'il n'y a que des colonnes qui peuvent être extraites de building_table et qu'elles existent ou non, elles seront prises de building_table
Puis passez nil
ou ce qui n'existe pas dans la position respective des api_keys
. Ce n'est même pas près d'élégant, c'est l'approche très courante utilisée partout dans le code ruby.
Je pense qu'il y a des solutions «intelligentes» suggérées, mais votre approche est facile à lire et à comprendre, et vous devriez vous y tenir.