5

Мне интересно, какой самый простой/самый элегантный способ выбора атрибутов из моделей join в has_many: через ассоциации.Элегантный выбор атрибутов из has_many: через модели объединения в Rails

Допустит, у нас есть товары, каталоги и CatalogItems со следующим пунктом классом:

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

Кроме того, позволяет сказать, что CatalogueItems имеет атрибут позиции и что есть только один CatalogueItem между любым каталогом и любым элементом ,

Наиболее очевидный, но немного расстраивает способ получить атрибут положения является:

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

Это раздражает, потому что кажется, что мы должны быть в состоянии сделать @ item.catalogs.first.position, так как мы имеем полностью укажите, какую позицию мы хотим: тот, который соответствует первому из каталогов @ item.

Единственный способ я нашел, чтобы получить это:

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. В одном случае позиция будет там, а в другой - нет.

У кого-нибудь есть хорошее решение?

Спасибо.

ответ

0

Вы можете сделать что-то вроде этого:

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

Или вы можете обернуть его в в методе экземпляра товара модели:

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

, а затем просто назвать это так:

@item.position_in_first_catalogue 
+1

Метод экземпляра работает, но по-прежнему кажется, что должен быть лучший способ. Мне не нужен первый каталог, я просто использовал его в качестве примера. Думаю, вы могли бы сделать @ item.position_in_catalog (catalog_id). – arjun

+0

Да, это действительно легко переписать для @ otem.position_in_catalog (каталог). Однако я не вижу другого способа, как вы могли бы реализовать то, что хотите. –

+0

@ item.catalogs.first.position <- это вообще не указывает какую-либо позицию. С помощью @ item.catalogs вы просто указываете подмножество всех каталогов, из которых вы затем выбираете первый.Итак, что вы в конечном итоге - это просто каталог, который агностик о том, как вы его получили. –

-1

Вы должны иметь возможность сделать @ catalog.catalog_item.position, если вы предоставите другой конец ассоциации.

class Catalog < ActiveRecord::Base 
    belongs_to :catalog_item 
end 

Теперь вы можете сделать Catalog.first.catalog_item.position.

+0

Каталог has_many catalog_items и has_many элементов через catalog_items, так что это не совсем то, что я искал. – arjun

+0

Это не будет работать для отношений «многие ко многим», выраженных has_many: through. –

-2

Почему ты просто не

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

почему вы идете через каталоги? Это не имеет никакого смысла для меня, так как вы ищете первый ЛЮБОЙ каталог !?

+0

Я не уверен, что вы подразумеваете под «первым ЛЮБЫМ каталогом». В любом случае, я не обязательно ищу первый каталог - это был всего лишь пример. Скажем, что у предмета есть 50 каталогов, и я хочу, чтобы позиция позиции в каталоге # 6823 .. – arjun

+0

Я имею ввиду, похоже, вам нужно только первое положение из каталога_имя для текущего элемента, и каталоги нужны для этого запроса. – aivarsak

+0

Вы не знаете, какую позицию вы хотите от catalog_items. Если элемент принадлежит 50 каталогам, и вы хотите, чтобы это позиция в 47-м каталоге (но не знаете, в каком порядке находятся каталоги), вам нужен каталог. – arjun