Elegant selection of attributes from has_many: through union models in Rails

I am wondering what the easiest / most elegant way to select attributes from association models in has_many: through associations, is there.

Suppose we have items, catalogs, and CatalogItems with the following Item class:

class Item < ActiveRecord::Base
      has_many :catalog_items
      has_many :catalogs, :through => :catalog_items
end    

Also, say that CatalogItems has a position attribute and that there is only one CatalogItem between any catalog and any item.

The most obvious, but slightly frustrating way to get the position attribute:

@item         = Item.find(4)
@catalog      = @item.catalogs.first
@cat_item     = @item.catalog_items.first(:conditions => {:catalog_id => @catalog.id})
position      = @cat_item.position

This is annoying because it seems that we should be able to do @ item.catalogs.first.position, since we have completely determined which position we want: the one that corresponds to the first of the @ item directories.

The only way I found this is:

class Item < ActiveRecord::Base
      has_many :catalog_items
      has_many :catalogs, :through => :catalog_items, :select => "catalogue_items.position, catalogs.*"
end

Item.catalogs.first.position. - . , @catalogs @item.catalogs. , - .

- ?

.

+5
3

- :

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

Item:

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

:

@item.position_in_first_catalogue
0

@catalog.catalog_item.position, .

class Catalog < ActiveRecord::Base
  belongs_to :catalog_item
end

Catalog.first.catalog_item.position.

-1

Why don't you just

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

Why are you browsing catalogs? This makes no sense to me, since you are looking for the first ANY directory !?

-2
source

All Articles