32
votes

Hi I'm having trouble conceptualizing when to use :source and when to use :class for my more complex models.

Here I have an example of users with friends.

class User < ActiveRecord::Base
  ...
  has_many :friendships, :dependent => :destroy
  has_many :friends, :through => :friendships, :conditions => "status = 'accepted'"
  has_many :requested_friends, :through => :friendships, :source => :friend, :conditions => "status = 'requested'", :order => :created_at
  has_many :pending_friends, :through => :friendships, :source => :friend, :conditions => "status = 'pending'", :order => :created_at
end


class Friendship < ActiveRecord::Base
  attr_accessible :friend_id, :user_id, :status

  belongs_to :user
  belongs_to :friend, :class_name => "User", :foreign_key => 'friend_id'
end

Can someone explain why for Friendship it's :class_name instead of :source? Is this because that's just the pairing (has_many + :source , belongs_to + :class_name)?

2

2 Answers

27
votes

They are conceptually the same, just need to be different for different uses.

:source is used (optionally) to define the associated model name when you're using has_many through; :class_name is used (optionally) in a simple has many relationship. Both are needed only if Rails cannot figure out the class name on its own. See the documentation for has_many in the API here.

1
votes

Here are examples of usage of :source and :class_name.

has_many :subscribers, through: :subscriptions, source: :user

has_many :people, class_name: "Person"

As you can see when you use a through table you end up using source else you use class_name.

Look at the option examples in this link: http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_many