Me pregunto cuál es la forma más fácil/más elegante de seleccionar atributos de los modelos join en has_many: mediante asociaciones.Elegir elegantemente los atributos de has_mucho: mediante los modelos de unión en Rails
digamos que tenemos artículos, catálogos y CatalogItems con la siguiente clase de artículo:
class Item < ActiveRecord::Base
has_many :catalog_items
has_many :catalogs, :through => :catalog_items
end
Además, permite decir que CatalogueItems tiene un atributo de posición y de que sólo hay un CatalogueItem entre cualquier catálogo y cualquier elemento .
La manera más obvia, pero un poco frustrante para recuperar el atributo posición es:
@item = Item.find(4)
@catalog = @item.catalogs.first
@cat_item = @item.catalog_items.first(:conditions => {:catalog_id => @catalog.id})
position = @cat_item.position
Esto es molesto, ya que parece que debemos ser capaces de hacer @ item.catalogs.first.position ya que tenemos completamente especificó qué posición queremos: la que corresponde al primero de los catálogos de los artículos.
La única manera que he encontrado para conseguir esto es:
class Item < ActiveRecord::Base
has_many :catalog_items
has_many :catalogs, :through => :catalog_items, :select => "catalogue_items.position, catalogs.*"
end
ahora que puedo hacer Item.catalogs.first.position. Sin embargo, esto parece un truco: estoy agregando un atributo adicional en una instancia de catálogo. También abre la posibilidad de intentar usar una vista en dos situaciones diferentes donde llene @catalogs con Catalog.find o con @ item.catalogs. En un caso, la posición estará allí, y en el otro, no.
¿Alguien tiene una buena solución para esto?
Gracias.
El método de instancia funciona, pero todavía parece que debería haber una manera mejor. No quería específicamente el primer catálogo, solo lo estaba usando como ejemplo. Supongo que podrías hacer @ item.position_in_catalog (catalog_id). – arjun
Sí, es muy fácil volver a escribirlo para @ otem.position_in_catalog (catálogo). Sin embargo, no veo otra forma de cómo implementar lo que quieres. –
@ item.catalogs.first.position <- esto no especifica ninguna posición. Con @ item.catalogs, solo debe especificar un subconjunto de todos los catálogos, a partir de los cuales seleccionará el primero.Entonces, con lo que terminas es solo un catálogo, que es agnóstico sobre la forma en que lo obtuviste. –