2011-02-09 9 views
0

私はhas_and_belongs_to_manyマクロによって関連付けられたモデルXとモデルYを持っています。データベースには、モデルXとモデルYとの間の多対多の関係に関するデータを保持するテーブルがあります。Rails 3モデルのシリアル結合。多対多の関係をどのように関連付けるのですか?

モデルAはhas_manyマクロを介してモデルXに関連付けられています。だから、モデルAに関連するすべてのモデルYの目的を達成するために非常に単純なコマンドを実行するために、他の言葉で、のは、私は次のオブジェクトを持っているとしましょう:

objectA.kind_of? ModelA = true 
objectX.kind_of? ModelX = true 
objectY.kind_of? ModelY = true 

私はobjectA.objectYsを実行できるようにしたいとに戻ってきました私[オブジェクトY]。

これを行うには、私のモデル定義に何を入れなければなりませんか?

(I、モデルAに配置しようとしている:(1)has_many :modelY;及び(2)has_many :modelY, :through => :modelXどちらも右ではない。)

答えて

1

警告:通常1は、このような歪んだモデル名を使用しないであろう。モデルを仮定

は、次のようになります。

class ModelA < ActiveRecord::Base 
    has_many :model_xes 
end 

class ModelX < ActiveRecord::Base 
    belongs_to :model_a 
    has_and_belongs_to_many :model_ies, :class_name => 'ModelY', 
    :join_table => 'model_x_model_ies' 
end 

class ModelY < ActiveRecord::Base 
    has_and_belongs_to_many :model_xes, :class_name => 'ModelX', 
    :join_table => 'model_x_model_ies' 
end 

我々がModelYのを取得するためにスコープを作成することができ、すべてのModelXのモデルAに属する:

class ModelY < ActiveRecord::Base 
    scope :find_by_a, lambda { |a| joins(:model_xes).\ 
    where(:model_xes=>{:model_a_id=>a.id})} 
end 

、単純な方法へModelAのインスタンスでスコープを呼び出します。

class ModelA < ActiveRecord::Base 
    def ys 
    ModelY.find_by_a(self) 
    end 
end 

テストは次のようになります。

require 'spec_helper' 

describe ModelA do 
    before(:each) do 
    @a = ModelA.create(:name=>"a") 
    2.times { @a.model_xes.create(:name=>"x") } 
    end 

    it "relates model_x" do 
    @a.model_xes.count.should == 2 
    end 

    it "relates model y" do 
    x = @a.model_xes.first 
    x.model_ies.create 
    x.model_ies.count.should == 1 
    end 

    it "relates model y through model x" do 
    @a.model_xes.each do |x| 
     2.times { x.model_ies.create(:name=>"y") } 
    end 
    ys = @a.ys 
    ys.count.should == 4 
    ys.all? { |y| y.name == "y" }.should be_true 
    end 
end 

HABTMが不合格になっているので、代わりにhas_many :throughを使用することをお勧めします。

+0

あなたの非常に有益な答えに感謝します。 –

関連する問題