10

ポリモーフィック アソシエーションを使用する場合、一部の型にのみ存在するサブモデルに対してインクルードを実行できますか?

例:

class Container
  belongs_to :contents, :polymorphic => true
end
class Food
  has_one :container
  belongs_to :expiration
end
class Things
  has_one :container
end

ビューでは、次のようなことをしたいと思います:

<% c = Containers.all %>
<% if c.class == Food %>
  <%= food.expiration %>
<% end %>

したがって、c をロードするときに有効期限を熱心にロードしたいと思います。そうする方法はありますか?囲まれたすべてのタイプにサブモデルの有効期限があるわけではないため、通常の :include を定義するだけでエラーが発生します。

4

1 に答える 1

24

編集された回答

Rails は、ポリモーフィック タイプ列でフィルター処理を行うと、ポリモーフィック アソシエーションのイーガー ロードをサポートすることが最近わかりました。したがって、偽の関連付けを宣言する必要はありません。

class Container
  belongs_to :content, :polymorphic => true
end

Container次に、 by をクエリしますcontainer_type

containers_with_food = Container.find_all_by_content_type("Food", 
                           :include => :content)

containers_with_thing = Container.find_all_by_content_type("Thing", 
                           :include => :content)

古い回答

1 つのクエリにポリモーフィック オブジェクトを直接含める方法がないため、これはハックです。

class Container
  belongs_to :contents, :polymorphic => true
  # add dummy associations for all the contents.
  # this association should not be used directly
  belongs_to :food
  belongs_to :thing
end

Container次に、 by をクエリしますcontainer_type

containers_with_food = Container.find_all_by_content_type("Food", 
                           :include => :food)

containers_with_thing = Container.find_all_by_content_type("Thing", 
                           :include => :thing)

その結果、データベースへの 2 つの SQL 呼び出しが発生します (レールはすべてに対して 1 つの SQL を実行するため、実際には 4 つの呼び出しです:include) 。

コンテンツ タイプごとに異なる列セットが必要なため、1 つの SQL でこれを行う方法はありません。

警告:クラスのダミーの関連付けContentは、予期しない結果になるため、直接使用しないでください。

contents例:テーブルの最初のオブジェクトに食べ物が含まれているとします。

Content.first.food # will work
Content.first.thing

2 番目の呼び出しは機能しません。が指すオブジェクトThingと同じ ID を持つオブジェクトが得られる場合があります。FoodContent

于 2010-03-05T22:56:16.627 に答える