I'm creating a Rails app, and I have a model called User. In this model I have a boolean value called isagirl. A user must specify if it is a girl or not, which is done by two radio buttons. In my model I have this:
validates_presence_of :isagirl, :message => "You must be either a Boy or a Girl. If not, please contact us."
However, when I don't specify a sex, I'm seeing this:
Isagirl You must be either a Boy or a Girl.
as an error message. The problem is that 'Isagirl' must not be there in the error message. How can I disable that? And no, using CSS to hide it is no option.
Thanks
The way that I do this is to output the message without the field name. For example, I have a partial that outputs the error messages after validation fails.
<ul>
<% errors.each do |attribute, message| -%>
<% if message.is_a?(String)%>
<li><%= message %></li>
<% end %>
<% end -%>
</ul>
Notice that this does not output the attribute. You just need to make sure that all your messages makes sense without an attribute name.
In one of my projects I was using custom-err-msg plugin. With it when you specify error message this way:
:message => "^You must be either a Boy or a Girl. If not, please contact us."
(notice ^ at the begining) it won't print attribute name when printing errors. And you can use standard error_messages or error_messages_for helpers.
I don't know how to omit the attribute name in the validates_presence_of function (it can be painful without dirty hacking) but I would use validate function to achieve what you want:
protected
def validate
errors.add_to_base("You must be either a Boy or a Girl. If not, please contact us.") if params[:isagirl].blank?
end
I used specifically method blank? here because validates_presence_of is using blank? for the test you should get this same behavior.
add_to_base is adding general error messages that are not related to the attributes and this saves you from hacking the view.
I recommend using the errors.add_to_base option. Without knowing what your layout looks like, that's going to be the simplest way to get a plain error message to appear.
Related
I want to add 'Notice that you have to select all the images and related vehicles again.' to the end of any validation error, regardless of how many errors there are, so for example adding this text to the end of every error message isn't an option, because it will be shown many times if there is more than one error.
Is there any way to add particular text to the end of validation error message?
Tried to google but didn't found anything.
This is easily accomplished however it may be tedious depending on how many validations you have listed. I will give some examples so you can decide on what best suites your needs:
If using Rails' built-in validations (such as prescence, uniqueness, etc.) you can add your own message inside the validation along with the standard output or replace it completely with your own:
validates :username, :email, :title, :another_attribute,:omg_another_attribute, :password, presence: { :message => "cant be blank. Notice that you have to select all the images and related vehicles again for not filling out the form ya dumbo!"}
This will list the error message for every field they left blank. If you want to add an error just once at the end of all the error messages to remind them of this problem you can make a custom validation that checks for other errors and then appends its own, one time, at the end like:
#Make sure to put this custom validate method after all the other validators since they are run in order from top to bottom and you want to see if the others have failed
validate :add_blanket_error_when_one_or_more_errors_happen
def add_blanket_error_when_one_or_more_errors_happen
if self.errors.count > 0 then self.errors.add(:base, "Notice you were being dumb again and now have to fill more stuff out.") end
end
I normally add generic errors like this to the 'base' field but you can attach it to any field in your form if you dont want to add extra styling/markup. In your view if you chose to add it to the 'base' field you can put this message right at the top of the form if it exists by doing:
<% unless #the_form_object_youre_using_here.errors[:base].blank? %>
<div>
<span class="error-explanation"><%= #again_the_form_object_here.errors[:base].first %></span>
</div>
<% end %>
This will also let you style the span etc.
Unfortunately there is no simple one-liner you can add to your model to append a blanket message to all failed validations. Even trying something seemingly harmless like a custom validation to accomplish it(DONT TRY THIS UNLESS YOU HAVE your task-manager ready because it will cause a memory leak and even make your computer crash if you dont kill the process quickly)
**DONT DO IT IF YOU ENJOY COORS LIGHT OR PREFER LONG WALKS ON THE BEACH**
validate :append_messages_to_all_failed_validations
def append_messages_to_all_failed_validations
self.errors.each do |attribute, error|
#**YOU SHOULDNT BE DOING THIS LOL**
self.errors[attribute.to_sym] = "#{error} plus some"
end
end
I have a form used for creating a team (the model is Team).
The form adds members to the team (via the model TeamMember).
Each team works for a company. All users belong to a company.
I currently have a validation on the TeamMember model which prevents a user from becoming a team member when the user works for a different company than the team works for.
Recently, I've been asked to modify this functionality, since there are occasions when a team needs to add a member who works for a different company.
My simple validation has now become complicated.
I now need to provide a warning when a proposed team member works for a different company, and give the user a chance to confirm (yes/no) whether this is ok before saving the change.
What is a clean, rails-friendly way to accomplish this? I imagine there is an Ajax solution (maybe a lightbox), but I'm not sure the best way to implement it or whether someone already has a clever Gem/Plugin to handle this situation.
I would use a custom validation for this, as you are now, and add a modifiable attribute to the model that doesn't save to the db. For example:
class TeamMember < ActiveRecord::Base
attr_accessor :user_confirmed
after_intialize :setup
def setup
self.user_confirmed = false
end
end
What you need to do is add a check in your validation method if self.user_confirmed is false. If it is, in addition to the db relation you described above, make it invalid. Then on your view, add an if statement:
<% if #team_member.errors[:key_you_use_to_add_to_base].first == "Error Message" %>
<%= f.label :user_confirmed, "User works for another company, are you sure?" %>
<%= f.check_box :user_confirmed, {}, "true", "false" %>
<% end %>
Keep in mind since check_box method uses strings, youll need to convert the result of that attribute in your params hash to a boolean.
I think that should do it. Note that you may need to adjust the if statement if any other validation errors might be added to the same key.
i'm creating an application where i need to send a private message to a user and ask him/her for a confirmation on whether they would like to join or not. I have created a private message module and whenever i want to send a message, i do something like :
def sendMessage(attributes)
subject = 'whatever'
body = 'whatever'
current_user.sendMessage(current_user, subject, body)
end
Then, i get this message and print it out to the needed places, using <%=h %> for escaping stuff. My problem now is, what happens if i want to include 's or even more importantly <%= link_to %> inside that ?
How can i insert such things to be printed out and also be careful about escaping the user provided attributes ? I was thinking of creating sort of like a partial to do this for me, but i would certainly like to hear what you think about it.
Thank you :)
First off, you probably should name your method send_message since that tends to be the convention in Ruby and Rails.
For the question, why not do this:
<p><%=h user_submitted_info %> and check out this <%= link_to "Awesome Link", "/" %></p>
This will escape the user submitted content but leave the link_to alone. Why does the user submitted content and the link need to be in the same ERB tags?
When you set a validation message in paperclip, such as
validates_attachment_presence, :image, :message => 'xxxx'
The custom message comes automatically prefixed with the name of the field, even though it has been overwritten with the :message . How do you totally override the message and make it totally custom?
Edit: typo
Not a real solution but a Easy one is to skip paperclip validation and write custom one.
validate :check_content_type
def check_content_type
if !['image/jpeg', 'image/gif','image/png'].include?(self.image_content_type)
errors.add_to_base("Image '#{self.image_file_name}' is not a valid image type") # or errors.add
end
end
I hope it can help
You actually want to do this inside your view rather than your model and it's actually quite straight forward. We're just going to loop through the errors, and when the one for your attachment comes up we'll ignore the field name:
<ul>
<% #myObject.errors.keys.each do |field| %>
<% #myObject.errors[field].each do |msg| %>
<% if field == :image_file_name %>
<li><%= msg %></li>
<% else %>
<li><%= field.to_s + " " + msg %></li>
<% end %>
<% end %>
<% end %>
</ul>
Replacing #myObject with the name of your model that should display only the message set to your attachment validation errors. This is just a simple example that displays them inline with the rest, but of course you could do anything you like with the messages. It's important to keep the name of the field that had the error in case you want to program any logic thats specific to its failure without having to rely on the error message staying exactly the same forever.
It's standard Rails behavior to show include the attribute name before the validation errors. You have a few options to work around this behavior:
Make your error message OK to have the attribute name prepended :)
Use a different error message formatter. It's pretty easy to write your own helper to iterate through an #object.errors and wrap messages in HTML tags. I prefer to use the error messages in-line near the fields so we always skip the attribute name.
Custom validation which adds the errors to base. This is easy, but wrong, since you're suggesting there's a validation error on a field. Still may solve your problem.
Override humanized_attribute_name for that attribute to hide it. humanized_attribute_name is probably used elsewhere, so this may cause other issues.
.
HumanizedAttributesOverride = {
:image => ""
}
def self.human_attribute_name(attr)
HumanizedAttributesOverride[attr.to_sym] || super
end
I don't know if it's just a typo inside your question, but it should be:
validates_attachment_presence :image, :message => 'xxxx'
And I would not use :message to add a custom error message, but put it inside a locales file.
In my Rails CREATE controller for a model, if the name of the record already exists, via JS I'm outputting the following response:
<%=#space.errors%>
Which outputs:
permissionsis invalidnameThis project name is already in use
In the model I have:
validates_uniqueness_of :name :message => 'This project name is already in use'
How do I get rid of the noise: "permissionsis invalidname" for the life of me I can't find it in the docs? Apologies if I'm missing something hugely obvious.
The issue is that you are actually returning the array containing all the error objects.
What you actually want is:
<ul>
<% #space.errors.full_messages.each do |msg| %>
<li><%=h msg %></li>
<% end %>
</ul>
This will give you a list of the errors.
I'm also pretty sure there's a nicer way to do this (i.e. some sort of helper built in to rails), but I haven't been able to find it in the docs for rails 3.