2009-01-09 47 views
5

我想知道從has_many:through關聯中選擇連接模型中屬性的最簡單/最優雅的方式是什麼。從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。但是,這看起來有點像黑客 - 我在Catalog實例上添加了一個額外的屬性。它還打開了在兩種不同的情況下嘗試使用視圖的可能性,其中我使用Catalog.find或@ item.catalogs填充@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 2009-01-09 21:55:03

+0

是的,它很容易重寫爲@ otem.position_in_catalog(目錄)。但是,我沒有看到任何其他方式如何實現你想要的。 – 2009-01-09 23:11:31

+0

@ item.catalogs.first.position < - 這根本沒有指定任何位置。使用@ item.catalogs,您只需指定所有目錄的子集,然後選擇第一個目錄。所以,你最終得到的只是一個目錄,它對你獲得它的方式是不可知的。 – 2009-01-09 23:19:49

-1

如果您提供關聯的另一端,您應該可以執行@ catalog.catalog_item.position。

class Catalog < ActiveRecord::Base 
    belongs_to :catalog_item 
end 

現在您可以執行Catalog.first.catalog_item.position。

-2

你爲什麼不只是

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

你爲什麼去通過目錄?這對我來說沒有任何意義,因爲你正在尋找第一個任何目錄!?

相關問題