The following are my three models: many users can each have many products (and vice versa) through an associations model.
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
This works great. But now I want to add 2 different association types, a 'strong-association' and 'weak-association' on top of the original association.
What is the best way to go about this?
So far I've considered 1) adding a type column to my association table to specify whether it is a strong/medium/weak association 2) adding a strong-association and also a weak-association record. Both methods seem troublesome when I want to display only a particular association type in my rails view.
I also want to be able to easily change the association type in my project.
You should definitely add a new field to your associations join table: this is the correct way to store this relationship. There's various things you could do after that.
You could add some new has_many associations:
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
And then do something like (on the page)
<h2>Strongly association users</h2>
<% @product.strong_associated_users.each do |user| %>
...show user info here
<% end %>
Or, you could not bother with the new has_many associations, and just split the association records up on the page:
<% 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 %>