views:

75

answers:

2

I have a Rails application that I'm in the process of designing. I have a separate model that needs to link to only 2 of one model. Specifically, my "evaluation"s have 2 "member"s, an evaluator, and an evaluatee. They also have a few other pieces of information, too but they should not be relevant to this.

What is the best way to represent this? Would 2 foreign keys in the evaluation be best, or a many-many relationship between the evaluations and the members? Would there be some other option that would work even better?

I would initially think many to many, but since there is a defined number on one side of the relationship I question the applicability here. To my knowledge, many-to-many generally implies that the number on each side of the relation is variable.

+1  A: 

You probably want two different associations, possibly with the same class:

class Member < ActiveRecord::Base
  has_many :evaluations_out, :class_name => 'evaluation', :as => :evaluator
  has_many :evaluations_in, :class_name => 'evaluation', :as => :evaluatee
end

class Evaluation < ActiveRecord::Base
  belongs_to :evaluator, :class_name => 'member'
  belongs_to :evaluatee, :class_name => 'member'
end
James A. Rosen
+1 agreed. If the system is such that there will always be precisely 2 relationships, 2 FKs are best. If there may be a likely future use case where you may have more than 2, thats when you should probably use a many-to-many.
DanSingerman
And in the case where there are an arbitrary number, but each relationship has a type (evaluator/evaluatee), then you probably want an intermediary model. So it becomes three models -- two with one 1:n and one 1:n-through, and one model with two 1:ns.
James A. Rosen
Javier's solution below makes a good point: those :class_names might have to be capitalized. The :foreign_keys are redundant if they're the same as the first argument to belongs_to (the association name).
James A. Rosen
A: 

I haven't tested it myself and it might sound a little adventurous, but I think that could work:

Evaluation Model

class Evaluation < ActiveRecord::Base 
  belongs_to :evaluator, :class_name => "Member", :foreign_key => "evaluator_id"
  belongs_to :evaluatee, :class_name => "Member", :foreign_key => "evaluatee_id"

end

Member Model

class Member < ActiveRecord::Base
  has_many :evaluators, :class_name => "Evaluation", :foreign_key => "evaluator_id"
  has_many :evaluatees, :class_name => "Evaluation", :foreign_key => "evaluatee_id"

end
Javier