What is the best way to handle a 4-sided relationship between two models?
I have two models: Company and User
In this situation:
- A company can follow another company.
- The user can follow the company.
- A user can follow another user.
What is the best way to define relationships and what would the join model look like?
Also, are there any guidelines for dealing with such situations?
Update
Sorry, this has not been mentioned before. I know different types of relationships. My question is ' which is the best fit ?
source to share
Thanks to polymorphic associations, we can put all relationships in one table that looks like this:
create_table :follows do |t|
t.references :followable, :polymorphic => true
t.references :followed_by, :polymorphic => true
end
Then the models:
class User < ActiveRecord::Base
has_many :following_objects, :class_name => 'Follow', :as => :followed_by
has_many :followed_objects, :class_name => 'Follow', :as => :followable
end
class Company < ActiveRecord::Base
has_many :following_objects, :class_name => 'Follow', :as => :followed_by
has_many :followed_objects, :class_name => 'Follow', :as => :followable
end
class Follow < ActiveRecord::Base
belongs_to :followable, :polymorphic => true
belongs_to :followed_by, :polymorphic => true
end
Sorry for the ugly names.
source to share
As for your question, I suggest you go through a couple of Railscasts videos:
- http://railscasts.com/episodes/47-two-many-to-many
- http://railscasts.com/episodes/154-polymorphic-association
And it is described very well on the RubyonRails website.
I would say, look at them in your case:
- http://guides.rubyonrails.org/association_basics.html#the-has_many-through-association
- http://guides.rubyonrails.org/association_basics.html#the-has_and_belongs_to_many-association
Hope this helps you.
source to share
The basic idea would be to use two associative bindings :
- User -> Friendship <- User
- Company → Partnership <- Company
models /user.rb
has_many :friendships
has_many :friends, :through => :friendships
has_many :inverse_friendships, :class_name => "Friendship", :foreign_key => "friend_id"
has_many :inverse_friends, :through => :inverse_friendships, :source => :user
models / friendship.rb
belongs_to :user
belongs_to :friend, :class_name => "User"
models /company.rb
has_many :partnerships
has_many :partners, :through => :partnerships
has_many :inverse_partnerships, :class_name => "Partnership", :foreign_key => "partner_id"
has_many :inverse_partners, :through => :inverse_partnerships, :source => :company
models / partner.rb
belongs_to :company
belongs_to :partner, :class_name => "Company"
And one many-to-many association :
- User -> CompanyUser <- Company
models / user.rb
has_and_belongs_to_many :companies
models / company.rb
has_and_belongs_to_many :users
So, for this implementation, you will need 5 tables (users, friends, companies, partners and companies) if you are using an RDBMS.
You can get a good example in this screencast:
http://railscasts.com/episodes/163-self-referential-association
source to share