Je me demande quelle est la manière la plus simple/la plus élégante de sélectionner des attributs à partir de modèles de jointure dans has_many: through associations.Sélection élégante des attributs de has_many: via les modèles de jointure dans Rails
Disons que nous avons des articles, des catalogues et CatalogItems avec les éléments suivants classe d'objet:
class Item < ActiveRecord::Base
has_many :catalog_items
has_many :catalogs, :through => :catalog_items
end
De plus, permet de dire que CatalogueItems a un attribut de position et qu'il n'y a qu'un seul CatalogueItem entre un catalogue et un article .
La façon la plus évidente, mais un peu frustrant pour récupérer l'attribut de position est la suivante:
@item = Item.find(4)
@catalog = @item.catalogs.first
@cat_item = @item.catalog_items.first(:conditions => {:catalog_id => @catalog.id})
position = @cat_item.position
Ceci est gênant car il semble que nous devrions être en mesure de le faire @ item.catalogs.first.position puisque nous avons complètement spécifié quelle position nous voulons: celle qui correspond au premier des catalogues de @ item.
La seule façon que j'ai trouvé pour y arriver est:
class Item < ActiveRecord::Base
has_many :catalog_items
has_many :catalogs, :through => :catalog_items, :select => "catalogue_items.position, catalogs.*"
end
Maintenant, je peux faire Item.catalogs.first.position. Cependant, cela semble un peu un hack - j'ajoute un attribut supplémentaire sur une instance de catalogue. Cela ouvre également la possibilité d'essayer d'utiliser une vue dans deux situations différentes où je remplis @catalogs avec un fichier Catalog.find ou avec un fichier @ item.catalogs. Dans un cas, la position sera là, et dans l'autre, ce ne sera pas le cas.
Est-ce que quelqu'un a une bonne solution à cela?
Merci.
La méthode d'instance fonctionne, mais il semble tout de même qu'il devrait y avoir une meilleure solution. Je ne voulais pas spécifiquement le premier catalogue, je l'utilisais juste comme exemple. Je suppose que vous pouvez faire @ item.position_in_catalog (catalog_id). – arjun
Oui, c'est vraiment facile de le réécrire pour @ otem.position_in_catalog (catalogue). Cependant, je ne vois pas d'autre moyen de mettre en œuvre ce que vous voulez. –
@ item.catalogs.first.position <- ceci ne spécifie aucune position. Avec @ item.catalogs, il vous suffit de spécifier un sous-ensemble de tous les catalogues, à partir duquel vous sélectionnez le premier.Donc, ce que vous finissez avec est juste un catalogue, qui est agnostique sur la façon dont vous l'avez obtenu. –