In my Rails 4 app I have an email field. My model ensures that no duplicate values are stored using the following:
validates :email, presence: true, uniqueness: { case_sensitive: false }
This has served me well while I wasn't bothered about confirming email addresses but now I want to confirm them before they are able to login. This means that I only want to confirm uniqueness if another field confirmed is true.
Is there an in-built way to tackle this at all or will it be my own validation rule that's required?
You can pass options such as a record set to a uniqueness validator like so:
validates_uniqueness_of :email, conditions: -> { where(confirmed: true) }
Then it will only enforce uniqueness against confirmed records.
I believe this is what you want:
http://edgeguides.rubyonrails.org/active_record_validations.html#using-a-symbol-with-if-and-unless
Related
class Person < ApplicationRecord
validates :name, uniqueness: { case_sensitive: false }
end
When a model has above definition, what exactly is happening behind the scenes?
My guess is there exists some validates method and a parameter is passed with symbol name. What is second parameter? a hash with a value that is hash?
First validation :name lets know that Person is not valid without a name attribute.
Second validation uniqueness
This helper validates that the attribute's value is unique right before the object gets saved. It does not create a uniqueness constraint in the database, so it may happen that two different database connections create two records with the same value for a column that you intend to be unique. To avoid that, you must create a unique index on that column in your database.
Third { case_sensitive: false }
There is also a case_sensitive option that you can use to define whether the uniqueness constraint will be case sensitive or not. This option defaults to true
Finally validates :name, uniqueness: { case_sensitive: false }
It means in Person model name attribute must be present with uniqueness not be case sensitive.
I am working in my ruby on rails assignment that will let users input their first name, middle name and last name. Now I want to validate each of them using uniqueness. Of course, if the first, middle and last name already exist, it cannot be created. But if the first name is the only one that has and existing match in the database and the middle and last name is different, it should be created. Another example is that if only the middle name has an existing match in the database and the other two are different. The problem is that if I use, validates :first_name, :middle_name, :last_name, uniqueness: true, it will not cover the said conditions. Please help me
What you're looking for is :scope keyword
Try
validates :first_name, uniqueness: { scope: [:last_name, :middle_name] }
And refer to documentation
What would cause me not to be able to edit a User record using Rails Admin?
I can edit every other record fine, but when I try to edit this particular record I get this error:
User failed to be updated
- Email has already been taken
I'm using Devise for user signups, along with this model validation:
validates :email, uniqueness: { case_sensitive: false }
I go to the user edit form in Rails Admin, change some other field and on submit get the error above. It's really strange and I'm trying to see if there may be any ideas I may have missed.
Why would this validation trigger when I'm just updating the record? There is only one record with that particular email value, and that's the one I'm editing.
Try limiting your validation to create and see whether that makes a difference.
validates :email, uniqueness: { case_sensitive: false }, on: :create
Your code for validating email is right.
You got the default validation message "Email has already been taken", because you have the same email in your Users Table.
It's either part of a seed file so you don't remember saving it.
Or has been saved by other user.
Please try to search it, like:
User.find_by(:email => "test_mail_here")
# so you can check duplication ef email.
The default validation of your code is for: create & update
You can use :
validates :email, uniqueness: { case_sensitive: false }, on: :create
But, I think much better NOT to used it.
Best solution for me, is update or delete the duplicate email. So you can use the full functionality of validates method again.
I'm using devise and I'm trying to add an email_confirmation input, I want my users to type their email address twice in order to make sure that they didn't make any mistake (like the password_confirmation input). I have searched for a solution for days but all I can find is how to "verify" an email address. How would the validation work ? Any answer/suggestion will be greatly appreciated.
To confirm their email address, add the field email_confirmation to the form:
run rails generate devise:views so that devise views are available within the application.
add email_confirmation to the devise form.
Then allow this parameter to be passed to devise:
https://github.com/plataformatec/devise#strong-parameters
The last step is to add the validation to User model (or the model you use with devise):
validates :email, confirmation: true
You'll want to use a regular expression validation. Something like this should do the trick:
validates :email,
format: { with: /\A([^#\s]+)#((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i, message: 'Invalid email' }
That's assuming that by "verify" you mean simply "check that the thing the user entered looks like a valid email".
There's an additional step of verification, not taken by most apps, which checks that the email not only looks like a valid email, but actually is an email address that exists in real life. If that's what you're after, check out https://github.com/kamilc/email_verifier
VALID_EMAIL_REGEX = /\A[\w+\-.]+#[a-z\-.]+\.[a-z]+\z/i
validates :email, presence: true, length: { maximum: 255 },
format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }
I have an model, called Replay, that has 3 attributes, match_id, game_number, and uploader_id. Essentially, I would like a validation to enforce that an uploader does not upload a replay for a match with the same game number as a replay they have already uploaded for that match. I would like, however, for another user to be able to upload a replay for that match and game number.
The validation I am using now is:
validates :game_number, presence: true, uniqueness: { scope: :match_id }
But this does not take into account the uploader_id. Any help would be appreciated.
Try this:
validates :game_number, presence: true, uniqueness: { scope: [:match_id, :uploader_id] }