5

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.

Respuesta

0

Usted puede hacer algo como esto:

# which is basically same as your "frustrating way" of doing it 
@item.catalog_items.find_by_catalogue_id(@item.catalogs.first.id).position 

O se puede envolver en en un método de instancia del modelo de artículo:

def position_in_first_catalogue 
    self.catalog_items.find_by_catalogue_id(self.catalogs.first.id).position 
end 

y luego simplemente llamar así:

@item.position_in_first_catalogue 
+1

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

+0

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. –

+0

@ 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. –

-1

Debería poder hacer @ catalog.catalog_item.position si proporciona el otro extremo de la asociación.

class Catalog < ActiveRecord::Base 
    belongs_to :catalog_item 
end 

Ahora puede hacer Catalog.first.catalog_item.position.

+0

Un catálogo tiene muchos elementos de catálogo y tiene muchos elementos a través de catalog_items, así que esto no es exactamente lo que estaba buscando. Pero gracias. – arjun

+0

Esto no funcionará para la relación de muchos a muchos expresada por has_many: through. –

-2

¿Por qué no sólo

@item = Item.find(4) 
position = @item.catalog_items.first.position 

¿Por qué vas a través de catálogos? No tiene ningún sentido para mí ya que está buscando primero CUALQUIER catálogo?

+0

No estoy seguro de lo que quiere decir con "primero CUALQUIER catálogo". De todos modos, no estoy necesariamente buscando el primer catálogo, eso fue solo un ejemplo. Digamos que un artículo tiene 50 catálogos y quiero la posición del artículo en el catálogo # 6823 .. – arjun

+0

Quiero decir, parece que solo necesita la primera posición de catalog_items para el artículo actual y los catálogos son innecesarios para esta consulta. – aivarsak

+0

No sabe CUAL posición quiere de catalog_items. Si un elemento pertenece a 50 catálogos y desea su posición en el 47º catálogo (pero no sabe en qué orden están los catálogos), entonces necesita el catálogo. – arjun

Cuestiones relacionadas