Question

I am using the validates_existence_of gem. It works well except when I want to allow my foreign key to be nil.

Here are my models for User and Project. A project belongs_to a user and a contributor (a contributor is also a user), but the contributor can be nil.

Here is my user model:

class User < ActiveRecord::Base
  attr_accessible :first_name, :last_name
  has_many :projects, :dependent => :destroy
  has_many :user_trimester_statuses, :dependent => :destroy
end

And here is my project model:

class Project < ActiveRecord::Base
  attr_accessible :added, :amount, :contributor_id, :label, :ref, :trimester_id,    :user_id
  belongs_to :user
  belongs_to :contributor, :class_name => 'User'
  belongs_to :trimester
  validates :user, :existence => { :both => false }
  validates :trimester, :existence => { :both => false }
  validates :contributor, :existence => { :allow_nil => true, :both => false }
end

When I try to add a new project, I have an error if the user_id or trimester_id field is blank or invalid. But for the contributor_id field, there is no error thrown if the field is invalid. It goes through either way (valid, invalid, or nil).

What am I doing wrong? I am using ruby 2.0.0p0 and rails 3.2.13.

Was it helpful?

Solution

It looks like there is an open bug about this in the project.

https://github.com/perfectline/validates_existence/issues/15

You may have to write a simple custom validator for this case until this gets fixed. (or dig in and see if you can fix the issue yourself)

UPDATE: I just cloned the project and wrote a test to see what the issue was. It seems that when you add the allow_nil, the existence validator doesn't get called at all. I'm not sure why that is, but in the meantime, you can work around the bug in an easy way, by using a proc. instead of

validates :contributor, :existence => { :allow_nil => true, :both => false }

this would get the job done

validates_existence_of :contributor, :unless => Proc.new { |obj| obj.contributor_id.blank? }

I was able to prove that in my test case. (I went with the 'validates_existence_of' method, instead of 'validates', because I thought it was cleaner in this case)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top