1

I am trying to validate that two columns are unique in my User model. I've searched Google and from what I understand the following code will not work:

validates :login, :uniqueness=>true
validates :email, :uniqueness=>true

In my case doing that will validate the uniqueness of email, but will not validate the uniqueness of login. I set that login must be unique on the database. However, all that will do is generate a runtime error if it already exists. I don't want that error in production because it would result in a 500 internal server error, which the user would not understand.

Any ideas on how I could validate the uniqueness of both of these fields?

Authentication Used:

  • CanCan
  • Devise
  • Devise Invitable

Update:

From what I can tell the problem is being caused by Devise, specifically the validatable module, which validate email and password.

Update 2:

Removing the validatable module from Devise will result in neither checking for uniqueness.

Update 3:

It appears that devise is not causing the problem. Rather, a gem called Devise Invitable is. Removing this gem results in the validation being triggered. It also appears that this gem tries to force validations of the email field. It makes sense due to the nature of this gem, but shouldn't be blocking.

Travis Pessetto
  • 3,260
  • 4
  • 27
  • 55
  • 1
    Are you using an authentication gem? If so, that might be catching the validation. This should work, so there's a conflict upstream somewhere. – JohnMetta Oct 19 '12 at 16:39
  • @JohnMetta I'm using CanCan with Devise – Travis Pessetto Oct 19 '12 at 16:42
  • what you describe should work. but you could also try "validates_uniqueness_of :login, :email" - how does this runtime error look like? which version of rails are you using ? – tmaximini Oct 19 '12 at 17:06
  • @frankblizzard the runntime error states: ```ActiveRecord::RecordNotUnique in UsersController#create``` and I am using Rails 3.2.8 – Travis Pessetto Oct 19 '12 at 17:21

3 Answers3

9

Should be able to do it with scope, adding to the default validation by devise.

For Rails 3 versions :

validates :email, :uniqueness => {:scope => :login}

Ref:

Community
  • 1
  • 1
Prakash Murthy
  • 12,923
  • 3
  • 46
  • 74
  • When I try this solution I get ```rescue in block in validates': Unknown validator: 'ScopeValidator' (ArgumentError)``` when trying to start the rails server. – Travis Pessetto Oct 19 '12 at 18:06
  • Verified that I too got the same error. My bad; I had given the Rails 2 version of the solution. I updated the answer with the Rails 3 version of the solution. Verified it works on my side. The order of attributes is important. The solution I gave validates the uniqueness of new email in combination with existing logins. – Prakash Murthy Oct 19 '12 at 19:51
  • While your solution may be valid. I think the underlying problem comes from devise_invitable, removal of this gem result in the right behavior but cripples some of the functionality that is required for the application (being what that gem is suppose to do). – Travis Pessetto Oct 19 '12 at 19:57
  • I doubt devise_invitable functionality would interfere with the validations part. I suggest trying the scoped validation and verify that email & login combination can be set as unique. – Prakash Murthy Oct 19 '12 at 20:23
  • The two original validations work after config.validate_on_invite = true. If not then it does not work. I think it is because instead of calling .save .invite!(params) is called to send an email to the user and bypass the password validation. – Travis Pessetto Oct 19 '12 at 20:25
0

The problem was with the devise_invitable gem. In the devise initializer I had to set

  config.validate_on_invite = true

to make sure the validations were executed, the default is false. I also had to remove the devise validatable module.

Travis Pessetto
  • 3,260
  • 4
  • 27
  • 55
0

The code works perfectly fine on the Rails 3.2.8..I have tested on it...

maybe there are some problems with your gems...

Aditya Kapoor
  • 1,542
  • 10
  • 13