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?


Sorry, this has not been mentioned before. I know different types of relationships. My question is ' which is the best fit ?


source to share

3 answers

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


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

class Company < ActiveRecord::Base
    has_many :following_objects, :class_name => 'Follow', :as => :followed_by
    has_many :followed_objects, :class_name => 'Follow', :as => :followable

class Follow < ActiveRecord::Base
    belongs_to :followable, :polymorphic => true
    belongs_to :followed_by, :polymorphic => true


Sorry for the ugly names.



As for your question, I suggest you go through a couple of Railscasts videos:

And it is described very well on the RubyonRails website.

I would say, look at them in your case:

Hope this helps you.



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:




All Articles