2013-07-23 35 views
0

我想了解导轨协会请解释导轨has_many通过协会

我有下面的表,我已经定义了他们的关系,任何一个请帮我理解。 这些表格是产品,产品销售商和分销商。 每个产品都有一个分销商,经销商进行多个产品

我定义这些作为

class Product < ActiveRecord::Base 
    has_one :product_distributor 
    has_one :distributor, through: :product_distributor 
end 
class ProductDistributor < ActiveRecord::Base 
    belongs_to :products 
    belongs_to :distributors 
end 
class Distributor < ActiveRecord::Base 
    has_many :product_distributors 
    has_many :products, through: :product_distributors 
end 

这是正确的吗?如果不是,我该如何纠正它?

回答

0

我觉得问题在于Distributors类名,因为它是复数。当您说类似has_many :distributors的东西时,Rails默认会链接到Distributor类,但在您的情况下,类名称是Distributors

添加class_name选项,以你们的关系的声明应该工作:

class Product < ActiveRecord::Base 
    has_one :product_distributor 
    has_one :distributor, through: :product_distributor, class_name: 'Distributors' 
end 
class ProductDistributor < ActiveRecord::Base 
    belongs_to :product 
    belongs_to :distributor, class_name: 'Distributors' 
end 
class Distributors < ActiveRecord::Base 
    has_many :product_distributors 
    has_many :products, through: :product_distributors 
end 

另外请注意,您的belongs_to应该是单数不是复数。请详细阅读协会指南:http://guides.rubyonrails.org/association_basics.html

+0

感谢Vinod的回答。 “经销商”类名是我在stackoverflow中犯的一个错字。对于那个很抱歉。 – user2056101

+0

@ user2056101,发生了!我认为你仍然需要修正'belongs_to'声明,你的'belongs_to:products'和'belongs_to:distributor'应该是单数而不是复数形式的答案。您可以忽略'class_name',因为您已更正模型名称。 – vee

0

正如我所看到的,产品有一个(属于)分销商,而分销商有很多产品。所以,你不需要使用ProductDistributor

class Product < ActiveRecord::Base 
    belongs_to :distributor 
end 

class Distributors < ActiveRecord::Base 
    has_many :products 
end 

只需添加列* distributor_id *至产品

我建议你阅读Active Record Associations Guid了解协会

+0

感谢您的回答。我无法更改产品表以包含distributor_id。这就是我拥有product_distributor的原因。即我需要能够从product.distributor等产品访问分销商,但是我不能也不能更改产品表。 – user2056101

0

使用has_many through:的原因是你需要使用未在标准Rails命名约定中命名的连接表。在这种情况下,ProductDistributor有一个关联的表(product_distributors),因为Rails约定将表按照字典顺序排列在名称中并将它们复数化。 Rails表名将是distributors_products。如果您使用外键创建了distributorsproducts表的ID,则不需要指定联接表,您可以在产品上说has_and_belongs_to_many :distributors,在分销商上说说has_and_belongs_to_many :products

坦率地说,你拥有的东西并不完全正确。产品和分销商之间有许多关系。如果您确实想要在产品和分销商之间建立many_to_one关系,则应进行以下更改:

模式更改:删除product_distributors表并将产品的外键添加到分销商。

drop_table :product_distributors 
change_table :products do |t| 
    t.references :distributors 
end 

型号更改:删除ProductDistributor的型号,并将产品和分销商更改为直接引用对方。另请注意,分销商已更名为分销商。

class Product < ActiveRecord::Base 
    belongs_to :distributor 
end 

class Distributor < ActiveRecord::Base 
    has_many :products 
end 
+0

谢谢肖恩回答。我无法更改产品表。即在产品表中具有distributor_id是不可接受的。当我们添加t.reference:分销商时,它会将distributor_id添加到产品表中。本质上,我想要模型提供的便利参考机制,但不能更改模式,除非我可以添加新表distributor_products。 – user2056101