2个模型之间的多种关联类型

时间:2014-03-18 16:25:05

标签: ruby-on-rails ruby model model-associations

以下是我的三个模型:许多用户可以通过关联模型获得许多产品(反之亦然)。

class Product < ActiveRecord::Base
  has_many :associations
  has_many :users, :through => :associations
end

class User < ActiveRecord::Base
  has_many :associations
  has_many :products, :through => :associations
end

class Association < ActiveRecord::Base
  belongs_to :user
  belongs_to :product
end

这很有效。但现在我想在原始关联之上添加2种不同的关联类型,“强关联”和“弱关联”。

最好的方法是什么?

到目前为止,我已经考虑过1)在我的关联表中添加一个类型列,以指定它是强/中/弱关联2)添加强关联还是弱关联记录。当我想在rails视图中仅显示特定的关联类型时,这两种方法看起来都很麻烦。

我还希望能够轻松更改项目中的关联类型。

2 个答案:

答案 0 :(得分:1)

如果要更改关联类型,我建议您为关联表添加额外列。您可以通过首先收集所有关联然后调用#select之类的方法来筛选出要在控制器操作中显示的记录类型。例如,要获得所有“弱”关联,您可以在控制器操作中使用以下代码(我只是使用“show”操作作为示例。我不确定您的情况需要什么):

def show
  @products = current_user.products.select! { |p| p.association_type == "weak" } 
  #associations scoped through current_user
  #also, asociation_type is just a placeholder name for whatever you name that extra column

  render :show #@products are all products with "weak" association
end

您可以根据所需的关联类型更改所选内容。

答案 1 :(得分:1)

您绝对应该在关联连接表中添加新字段:这是存储此关系的正确方法。在那之后你可以做各种各样的事情。

您可以添加一些新的has_many关联:

class Product < ActiveRecord::Base
  has_many :associations
  has_many :users, :through => :associations
  has_many :weak_associated_users, :class_name => "User", :through => :associations, :source => :user, :conditions => ["associations.strength = ?", "weak"]
  has_many :medium_associated_users, :class_name => "User", :through => :associations, :source => :user, :conditions => ["associations.strength = ?", "medium"]
  has_many :strong_associated_users, :class_name => "User", :through => :associations, :source => :user, :conditions => ["associations.strength = ?", "strong"]
end

class User < ActiveRecord::Base
  has_many :associations
  has_many :products, :through => :associations
  has_many :weak_associated_products, :class_name => "Product", :through => :associations, :source => :product, :conditions => ["associations.strength = ?", "weak"]
  has_many :medium_associated_products, :class_name => "Product", :through => :associations, :source => :product, :conditions => ["associations.strength = ?", "medium"]
  has_many :strong_associated_products, :class_name => "Product", :through => :associations, :source => :product, :conditions => ["associations.strength = ?", "strong"]     
end

#fields: user_id, product_id, strength
class Association < ActiveRecord::Base
  belongs_to :user
  belongs_to :product
end

然后执行(页面上)

之类的操作
<h2>Strongly association users</h2>
<% @product.strong_associated_users.each do |user| %>
  ...show user info here
<% end %>

或者,您无法使用新的has_many关联,只需在页面上拆分关联记录:

<% grouped = @product.associations.find(:all, :include => [:user]).group_by(&:strength) %>
<% ["weak", "medium", "strong"].each do |strength| %>
  <% if associations = grouped[strength] %>
    <h2><%= strength %> associations</h2>#
    <% associations.each do |association| %>
      <% user = association.user %>
      ...show user info here
    <% end %>
  <% end %>
<% end %>