thank_you
thank_you

Reputation: 11107

Foreign Keys pointing to same Model

I have an User model

class User < ActiveRecord::Base
  attr_accessible :email, :name

  has_many :client_workouts
end

And a ClientWorkout model

class ClientWorkout < ActiveRecord::Base
  attr_accessible :client_id, :trainer_id, :workout_id

  belongs_to :client, :class_name => User, :foreign_key => 'client_id'

  belongs_to :trainer, :class_name => User, :foreign_key => 'trainer_id'  
end

I first want to know what or if I'm doing something wrong when writing the associations. Ideally I want to be able to call a query where I find the user's clients workouts where the user's id matches with client_id or trainer_id. So...

user.client_workouts.trainer???

Upvotes: 1

Views: 63

Answers (1)

jokklan
jokklan

Reputation: 3540

This will not work as rails assumes that the ClientWorkout have a user_id column. I don't think there is any way to make a has_many relation that matches two columns... Instead you could create a method like this:

class User < ActiveRecord::Base
  attr_accessible :email, :name

  has_many :client_workouts, :foreign_key => "client_id"

  has_many :trainer_workouts, :foreign_key => "trainer_id"

  def client_and_trainer_workouts
    ClientWorkouts.where("client_id = ? OR trainer_id = ?", id, id)
  end
end

Otherwise you could create a scope on the ClientWorkout model like this:

class ClientWorkout < ActiveRecord::Base
  attr_accessible :client_id, :trainer_id, :workout_id

  belongs_to :client, :class_name => User, :foreign_key => 'client_id'

  belongs_to :trainer, :class_name => User, :foreign_key => 'trainer_id'  

  scope :workouts_for_user, 
      lambda {|user| where("client_id = ? OR trainer_id = ?", user.id, user.id) }
end

You could also do both, and let the method on the use call the scope on the ClientWorkout.

Upvotes: 1

Related Questions