4

I am trying to add a counter cache on a a column in a self join association. I have two models User and followings. User has followers and followees, who are from the user table itself.

User.rb

  has_many :followings
  has_many :followers, :through => :followings
  has_many :followees, :through => :followings

Following.rb

class Following < ActiveRecord::Base
  attr_accessible :followee_id, :follower_id
  belongs_to :follower, :class_name => "User" 
  belongs_to :followee, :class_name => "User"
end

now i want to add counter cache on follower and followees. I have followers_count and followees_count columns in user table.

I tried

belongs_to :follower, :class_name => "User" , :counter_cache => true

But this doesn't return any data in the user table. Any help would be appreciated.

Learner
  • 4,596
  • 1
  • 20
  • 23
abhilash
  • 1,587
  • 2
  • 10
  • 17

2 Answers2

3

It was long-long time ago, but

User.rb

class User < ActiveRecord::Base
  has_many :followings_as_follower, class_name: 'Following', foreign_key: 'follower_id', dependent: :destroy
  has_many :followings_as_followee, class_name: 'Following', foreign_key: 'followee_id', dependent: :destroy
  has_many :followers, through: :followings_as_followee, source: :follower
  has_many :followees, through: :followings_as_follower,  source: :followee

  def follow?(user)
    followees.reload.include? user
  end

  def follow(user)
    return if follow?(user)
    followings_as_follower.create(followee: user)
  end

  def unfollow(user)
    return unless follow?(user)
    followings_as_follower.where(followee: user).first.destroy
  end
end

Following.rb

class Following < ActiveRecord::Base
  belongs_to :follower, class_name: 'User', counter_cache: :followees_count
  belongs_to :followee, class_name: 'User', counter_cache: :followers_count
  validates :follower, presence: true
  validates :followee, presence: true
  validates :followee, uniqueness: { scope: [:follower, :followee] }
end
Ximik
  • 2,435
  • 3
  • 27
  • 53
2

Try this,

belongs_to :follower, foreign_key: 'the_id_of_foreign_key', class_name: 'User', counter_cache: :followers_count

You can use the column_name instead of true in counter_cache.

Learner
  • 4,596
  • 1
  • 20
  • 23
  • I think i should explain ,id from user table is the foreign key and is being used or both columns. Let me try none the less. – abhilash Feb 28 '13 at 11:06
  • belongs_to :follower, :foreign_key => "id", :class_name => "User",:counter_cache => :followers_count – abhilash Feb 28 '13 at 11:11
  • 1
    Try this, `belongs_to :follower, :counter_cache => true` without class and foreign key name... – Learner Feb 28 '13 at 11:31
  • That doesn't work either. I am not sure what i am doing wrong here. From what i have read, i can see that my implementation of self join is different. followings table and user are joining each other but the counter i want is in user table. – abhilash Feb 28 '13 at 11:53