Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Right way to force uniqueness on a join model? (has_many :through)

I have a parent/child relationship via our users table, with models as such:

class User < ActiveRecord::Base

  # Parents relationship
  has_many :children_parents, :class_name => "ParentsChild", :foreign_key => "child_id", :dependent => :destroy
  has_many :parents, :through => :children_parents

  # Children relatiopnship
  has_many :parents_children, :class_name => "ParentsChild", :foreign_key => "parent_id", :dependent => :destroy
  has_many :children, :through => :parents_children
  ...
end

And in parents_child.rb:

class ParentsChild < ActiveRecord::Base

  belongs_to :parent, :class_name => "User"
  belongs_to :child, :class_name => "User"

end

Right now, it is possible in our "add children" form (just using vanilla nested attributes) to add the same user as a child multiple times for parents. I am not sure what the 'right' way to go about forcing uniqueness in the ParentsChild relationship, although I am leaning towards a unique index on (parent_id, child_id) at the database layer (using a migration of course).

I am sure I could also enforce uniqueness constraints in the UsersController::update method, but would prefer to avoid changing that code (right now it doesn't reference parents/children at all, thanks to nested attributes in the form/model) if possible. I am most concerned with making sure we use the "proper" solution. What is the 'right' or 'rails' way to do this?

like image 550
Brett Bender Avatar asked Oct 22 '10 15:10

Brett Bender


1 Answers

Using has_many :through, you can specify :uniq as an option, like this:

  has_many :parents, :through => :children_parents, :uniq => true
like image 51
Dominic Avatar answered Sep 21 '22 02:09

Dominic