请通过关联解释rails has_many

时间:2013-07-23 23:07:19

标签: ruby-on-rails

我正在尝试了解rails关联

我有以下表格,我要定义他们的关系,任何人都可以帮助我理解。 表格是Products,ProductDistributors和Distributors。 每个产品都有经销商,经销商有多个产品

我将这些定义为

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

这是对的吗?如果没有,我该如何纠正?

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

如我所见,产品有一个(属于)经销商,而经销商有很多产品。所以你不需要使用ProductDistributor

class Product < ActiveRecord::Base
   belongs_to :distributor
end

class Distributors < ActiveRecord::Base
   has_many :products
end

只需将列* distributor_id *添加到产品

即可

我建议您阅读Active Record Associations Guid以了解关联

答案 2 :(得分:0)

使用has_many through:的原因是您需要使用未在标准Rails命名约定中命名的连接表。在这种情况下,ProductDistributor有一个关联的表(product_distributors),因为Rails约定以字典顺序将表放在名称中并将它们复数化。 Rails表名称为distributors_products。如果您使用[{1}}和distributors表的ID的外键创建了这样一个表,则不需要指定连接表,只需在Products和products上说明has_and_belongs_to_many :distributors分销商{1}}。

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

架构更改:删除product_distributors表并将产品中的外键添加到分发服务器。

has_and_belongs_to_many :products

模型更改:删除ProductDistributor的模型,并更改Product and Distributor以直接引用彼此。另请注意,Distributors已重命名为Distributor。

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