I followed Devise's instructions for using usernames in addition to emails for logins. Works great except people can signup with duplicate usernames. If someone tries to signup with a duplicate email address, they are presented with this error message on the signup page:
1 error prohibited this user from being saved:
Email has already been taken
I want something very similar for usernames. How do I implement this?
You should use uniqueness validator. Add following into user.rb:
validates_uniqueness_of :username
more about this validator
Note that you probably want to make usernames unique, but also case-insensitive, so you don't end up with both username and Username:
class User < ApplicationRecord
validates :username, presence: true, uniqueness: { case_sensitive: false }
# Rest of user model
end
From the Devise wiki.
Related
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 am building an app where there are users and owners. Owners have many users and every user can belong_to one owner. It's the same model and the associations are built inside the models. The problem is that I want to be able to add and change the field values of them (e.g. user.department) and has_secure_password (password, password_confirmation) prevents me from doing so, as I have to enter a password & confirmation for the values to be persisted.
Can anyone tell me If I can bypass the password+confirmation validation for the owner ?
I am using the rails tutorial by Michael Hartl https://www.railstutorial.org/book/sign_up
has_secure_password validations: false
validates :password, :password_confirmation, :presence => true, :if => :password
Is one way to achieve that.
So I'm working on the registration aspect of the site currently. I have a main sign up which is just full name, email and password. (aka new.html.erb)
After you fill in that information I direct you to a new site (setup.html.erb) and ask for more info like city, country etc.
On that you also have the edit profile account.
I am trying to make my app more secure and adding restrictions and presence etc in the model. However how can I limit them.
Currently if I do
validates :email, presence: true,
and I go to a form that doesn't even contain the email for nor permits it I get an error up that I need to add an email.
Also how do I fix this: I make presence true, I input require in html5. But still if I go to my source code and just remove the form and push submit it saves and I can bypass adding info.
Currently if I do validates :email, presence: true,
and I go to a form that doesn't even contain the email for nor permits it I get an error up that I need to add an email.
Fix:
what you need is a conditional validation. If we look at rail guides it says
Sometimes it will make sense to validate an object only when a given predicate is satisfied. You can do that by using the :if and :unless options, which can take a symbol, a string, a Proc or an Array.
So in your model you could do something like:
class Order < ActiveRecord::Base
validates :email, presence: true, if: :need_to_validate?
def need_to_validate?
#your condition to check whether you want email validation or not
end
end
Update:
You can use params[:action] and params[:controller] smartly to check in which action and controller(hence which view) you currently are in so your method would be:
def need_to_validate?
params[:action] == your_view_action && params[:controller] == your_controller_name #your condition to check whether you want email validation or not
end
I want to avoid that somebody can create an user with the username 'Admin'. I use this username as Host to control some functions of my application. I know there is a expression to validate the uniqueness of an model record:
validates_uniqueness_of
But i only want that the username 'Admin' cant be created twice. I hope somebody has an idea! Thanks
You can use conditionals in your validation to do the following:
class Model
validates :username, uniqueness: true, if: :admin?
def admin?
username.downcase == 'admin'
end
end
With that said, they'd take away my developer card if I didn't discourage you from doing this.
Basing an admin account solely on whether the username is admin is setting yourself up for your security being compromised. Have a look at something like ActiveAdmin for managing your administrator accounts so that they're at the very least separated from your user accounts.
Or just validates_uniqueness_of :username, if: -> {username == 'admin'} in your model.