2011-02-09 38 views
0

我有模型X和模型Y通过has_and_belongs_to_many宏关联。数据库中有一张表保留了Model X和Model 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并已返回我[objectY]。

我必须在我的模型定义中放入什么才能做到这一点?

(我试图放置在模型A:(1)has_many :modelY;和(2)has_many :modelY, :through => :modelX既不是右边)

回答

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

我非常感谢你的答复。 – 2011-02-10 03:33:27

相关问题