-
Notifications
You must be signed in to change notification settings - Fork 48
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Doesn't work uniqueness #28
Comments
The To do this validation, you could do something like the below, starting off with a form object to collect and validate the data: class SignUpForm < Rectify::Form
attribute :first_name, String
attribute :last_name, String
attribute :email, String
validate :validate_email_uniqueness
private
def validate_email_uniqueness
return if unique_email?
errors.add(:email, "already in use")
end
def unique_email?
User.where("lower(email) = lower(?)", email).empty?
end
end Here we add a check at the time of validation to see if the email address exists (case insensitive). If not, then it passes validation. If it does exists, then validation fails. However, there is a potential race condition here in that between the time that you check for uniqueness and the time of saving, the email address might be taken by another request. To deal with this case, make sure you have a unique index on the database field to ensure that no duplicates can enter your database. Once that is in place we need a nice way to deal with the error that comes back from the database if you try to insert a duplicate. To do that, you could use a class SignUp < Rectify::Command
def initialize(form)
@form = form
end
def call
return broadcast(:invalid) if form.invalid?
User.create!(form.attributes)
broadcast(:ok)
rescue ActiveRecord::RecordNotUnique
broadcast(:race_non_unique_email)
end
private
attr_reader :form
end Which you would call from your controller like this: UsersController < ApplicationController
def new
@form = SignUpForm.new
end
def create
@form = SignUpForm.from_params(params)
SignUp.call(@form) do
on(:ok) { redirect_to dashboard_path }
on(:invalid) { render :new }
on(:race_non_unique_email) do
flash.now[:alert] = "The email address must be unique"
render :new
end
end
end
end This way you guarantee that the email address is unique and you handle the race condition in a nice way for the user (better than the Rails default I would say, as that doesn't handle the race condition). Anyway, hopefully that helps Thanks for the your interest in Rectify!! 💖 |
Hi! What about to make some optional validation of uniqueness and use model name as an attribute for this validation? And make it as an extension of I think I can implement it if you want. |
Thanks for the offer of help but I think in this case I would prefer to leave it to the developer to implement their uniqueness rules as this could get complex quite quickly. Thanks again for the question! 💖 |
Neither validate_uniqueness_of or unique: true for rails5
The text was updated successfully, but these errors were encountered: