J'ai deux modèles ci-dessous. Ils peuvent être expliqués comme suit:Association ActiveRecord: créer une nouvelle association ou une référence existante si les attributs associés correspondent
Un rapport a un rapport_détail (qui détermine les mois de début/fin). De nombreux rapports peuvent avoir le même détail de rapport, mais aucun détail de rapport ne peut être identique.
class Report < ActiveRecord::Base
# attr: name :: String
# attr: report_detail_id :: Integer
belongs_to :report_detail
accepts_nested_attributes_for :report_detail
end
class ReportDetail < ActiveRecord::Base
# attr: duration :: Integer
# attr: starting_month :: Integer
# attr: offset :: Integer
end
J'ai une contrainte unique sur un index sur ReportDetail pour [: durée: starting_month,: offset]
Ce que je suis en train d'accomplir est la suivante: Si un nouveau rapport a ReportDetail qui a une combinaison unique attrs (: duration,: starting_month,: offset), crée le nouveau ReportDetail et sauvegarde comme d'habitude. Si un rapport possède un ReportDetail dans lequel un objet ReportDetail existant a les mêmes attributs, associez les détails du rapport à ce ReportDetail et enregistrez le rapport.
J'ai eu que cela fonctionne par aliasing le poseur sur report_detail=
en utilisant un ReportDetail.find_or_create_by...
mais il est laid (et il crée également des entrées de ReportDetail inutiles mais juste par instanciation de nouveaux rapports avec les attributs de détail, et pour une raison que je ne pouvais pas obtenir le sauver pour fonctionner correctement en utilisant .find_or_initialize_by...
). J'ai également essayé un before_save
sur le ReportDetail pour dire, si je fais correspondre quelque chose d'autre, mettez self
à cet autre chose. Apparemment, vous ne pouvez pas vous définir comme ça.
Une idée de la meilleure façon de faire?
voir this gist pour mon setter actuel écrasera avec alias
Pouvez-vous publier le code pour aliaser le setter? Peut-être en tant qu'amplification et lien ici. On dirait que c'était sur la bonne voie, mais il peut y avoir un bug ou deux. –
ajouté ... il n'y a pas de bug dans ce code, tout fonctionne, mais je cherche une solution plus agréable. Mon plus gros boeuf est qu'il crée réellement un ReporDetail quand vous initialisez en utilisant l'essentiel ci-dessus. Je ne pouvais pas non plus le faire fonctionner correctement avec find_or_initialize_by car l'enregistrement sur l'association est censé avoir lieu avant cela, donc il ne finit pas de sauvegarder l'association dès le premier coup – brad