I have a validator in a class like the following
validates_uniqueness_of :email, {message: 'this is not a unique email :('}
What I would like is for this error to add a custom attribute to the errors object, like
{errors: {already_invited: true}}
How can I make this work?
You could do something like this
validates_uniqueness_of :email, {message: 'this is not a unique email :('}
validate :previous_invite
def previous_invite
#if already_invited is an attribute of the model then use
# errors.add(:already_invited, "true") otherwise add it to base
errors.add(:base, "already invited") if errors.added?(:email,'this is not a unique email :(')
end
You should not just add arbitrary keys to the errors but you can if you'd really like it is just considered poor form according to the docs:
attribute should be set to :base if the error is not directly associated with a single attribute.
Also messages will be treated as Strings not booleans. so it would not be already_invited: true but rather already_invited: "true"
Related
I have a User model with an email attribute. Various parts of my app conceive of an "email" differently; sometimes as a string, sometimes as a hash ({ token: 'foo', host: 'bar.com' }), sometimes as an object. This is bad; I want the concept of an email to be consistent wherever I use it.
So, I use an Email object that does what I want. I don't see any good reason to create an Email table; instead, I just want to create a new Email object corresponding to an email string whenever I need one. Therefore User looks like this:
class User < ActiveRecord::Base
def email
Email.new(read_attribute :email)
end
def email= email
write_attribute :email, email.to_s
end
end
However, this causes at least two issues:
I can't search for a user by email without an explicit call to to_s.
I can't run a uniqueness validation on the email column anymore. I get a TypeError: can't cast Email to string. (I can fix this with a custom validator.)
Questions:
Is there something wrong with this approach? The fact that it breaks my validation is a code smell to me.
Is there some way to get the existing validates :email, uniqueness: { case_sensitive: false } validation to work with these new accessor definitions?
I have a contact form and would like to show individual messages depending on what has failed.I would like to use flash messages. So from what i have read so far i can create a custom method (or i think it just overrides the one in place?)
So for example, i want to validate the presence of the name field
Class Message
attr_accessor :name
validates :name, :presence => true
def validate
if self.name < 0
errors.add(:name, "Name cannot be blank")
end
end
end
Within my controller i normally use a generic message
flash.now.alert = "Please Ensure all Fields are filled in"
Is there a way to call the particular message that failed validation?
Thanks
There is a plugin available, u can follow the below url
https://github.com/jeremydurham/custom-err-msg
Check the method validates because you can pass a message argument with the desired message.
validates :name, :presence => {:message => 'The name can't be blank.'}
I am having an issue while saving a user object in the database. I have two fields in the model (email and password) which are not allowed to be null in the database itself. Plus I have added validation in the model like
validates_presence_of :email, :message => "must be provided"
validates_presence_of :password, :message => "must be provided"
Now when I try to save the model from the create method of the controller, it invalidates the data and renders the new action again. However I have multiple error messages for each field
Email can't be blank
Email must be provided
Password can't be blank
Password must be provided
I don't need multiple error messages for the same one. How can I eliminate this?
Looks like you are validating in two different places. You have to figure it out the places...
If you are doing two different validation for a field and want to display one error message on a field at a time, you can do the following,
validates_presence_of :email, :message => "must be provided"
validates_uniqueness_of :email, :message => "must be unique",
:if => lambda { |a| a.errors.on(:email).blank? }
Looks like you are rendering errors twice. Check all your views, they can also be inherited.
When a user tries to create a record with a name that already exists, I want to show an error message like:
name "some name" has already been taken
I have been trying to do:
validates_uniqueness_of :name, :message => "#{name} has already been taken"
but this outputs the table name instead of the value of the name attribute
2 things:
The validation messages use the Rails I18n style interpolation, which is %{value}
The key is value rather than name, because in the context of internationalization, you don't really care about the rest of the model.
So your code should be:
validates_uniqueness_of :name, :message => '%{value} has already been taken'
It looks like you can pass a Proc to the message. When you do this, you get two parameters:
A symbol along the lines of :activerecord.errors.models.user.attributes.name.taken
A hash that looks something like `{:model=>"User", :attribute=>"Name", :value=>"My Name"}
So if you allow for two parameters on a proc, you can use the attributes[:value] item to get the name that was used:
validates_uniqueness_of :name,
:message => Proc.new { |error, attributes|
"#{attributes[:value]} has already been taken."
}
What version of Rails do you use?
If Rails 3. then as i understand you should use :message => '%{value} has already been taken'. I am not sure about Rails 2.3. - but in any case you can create your own custom validation that performs what you need.
I have a form on my site that lets users direct a message at other users, but I want to ensure that they can't direct a message at themselves.
The class has attributes :username and :target_user, and I just want to set a validation that checks to make sure that these attributes can't have the same value, before anything gets saved.
I figured it would look something like this:
validates_presence_of :user_id, :username, :target_user, :message, :tag
validate :username != :target_user
But clearly don't know enough Ruby to do it correctly.
Up at the top with your validations:
validate :username_does_not_equal_target
and then a private/protected method within your model code:
def username_does_not_equal_target
#errors.add(:base, "The username should not be the same as the target user") if self.username == self.target_user
end
OR to attach the error to a specific attribute:
def username_does_not_equal_target
#errors.add(:username, "should not be the same as the target user") if self.username == self.target_user
end
You can change the text of your error message or the name of your method.
to read more on errors: http://api.rubyonrails.org/classes/ActiveRecord/Errors.html
to read more on validations: http://api.rubyonrails.org/classes/ActiveRecord/Validations/ClassMethods.html
I hope this helps, happy coding!
Use validate
def validate
if self.username == self.target_user
self.errors.add :base, "You can't send message to yourself."
end
end