5

has_many :through アソシエーションの結合モデルから属性を選択する最も簡単でエレガントな方法は何だろうと思っています。

次の Item クラスを持つ Item、Catalog、および CatalogItems があるとします。

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

さらに、CatalogueItems に position 属性があり、任意のカタログと任意のアイテムの間に CatalogueItem が 1 つしかないとします。

位置属性を取得するための最も明白ですが、少しイライラする方法は次のとおりです。

@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 インスタンスに追加の属性を追加しています。また、@catalogs に Catalog.find または @item.catalogs を入力する 2 つの異なる状況でビューを使用しようとする可能性も開きます。ポジションが存在する場合もあれば、存在しない場合もあります。

誰もこれに対する良い解決策を持っていますか?

ありがとう。

4

4 に答える 4

0

次のようなことができます。

# 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
于 2009-01-09T14:29:59.927 に答える
-1

関連付けのもう一方の端を指定すると、 @catalog.catalog_item.position を実行できるはずです。

class Catalog < ActiveRecord::Base
  belongs_to :catalog_item
end

これで、Catalog.first.catalog_item.position を実行できます。

于 2009-01-09T19:00:42.813 に答える
-2

なぜあなたはただ

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

なぜカタログを見るのですか?あなたは最初のカタログを探しているので、私には意味がありません!?

于 2009-01-10T15:19:43.523 に答える