Reputation: 12748
Using Rails validation helpers-
validates_xxx_of :the_column, :message => "my message"
will generate a validation message :
the_column my message
Is there a way to turn-off the inclusion of the column name? (substitute xxx with any validation helper method)
Upvotes: 22
Views: 16675
Reputation: 136
Here's a fairly straightforward implementation that should do the trick. Notably, it only affects a single model (unlike most locale-based tricks I've seen) and isn't too heavy-handed.... it just modifies a single object:
class Widget < ActiveRecord::Base
validates_numericality_of :quantity, greater_than: 0, message: "numericality"
def errors
super.tap do |e|
e.extend(FixQuantityErrorMessage)
end
end
module FixQuantityErrorMessage
def full_message(attribute, message)
if attribute.to_s == 'quantity' && message == "numericality"
"You need at least one!"
else
super
end
end
end
end
Upvotes: 0
Reputation: 867
In rails 2, you can do on your model:
validate :test_validation
private
def test_validation
if error_condition
errors.add_to_base("Message")
end
end
In rails 3 or greater:
validate :test_validation
private
def test_validation
if error_condition
errors[:base] << "Message"
end
end
Upvotes: 1
Reputation: 7304
There is a customer error message gem that should do what you want
https://github.com/jeremydurham/custom-err-msg
It allows you to override the normal message construction, and define the complete message yourself like this:
:message=> "^ Your email address seems rather messed up, please try again"
Notice the ^ character, that tells rails NOT to prepend anything, just use the message exactly as defined, (except it removes the ^)
If you don't put a leading ^, then you get the normal rails generated error message.
Upvotes: 6
Reputation: 106
Took a look at the code here:
https://github.com/rails/rails/blob/master/activemodel/lib/active_model/errors.rb#L374
You can therefore set in your en.yml file:
en:
errors:
format: '%{message}'
This means you need to also set the full error message everywhere else but I guess this is preferable. Note, and I found this confusing, the errors format is not in the ActiveRecord namespace where I generally put the rest of my error messages.
Upvotes: 8
Reputation: 15950
For those who stumbled here (and potentially scrolled to bottom) looking for how to do this in later versions of Rails, here's some good news for you: it will be pretty simple to do this in Rails 4 after this pull request is merged. It may need some additional polishing for some scenarios, but progress has been made here.
Until then, you can monkey-patch Rails in your project with the pull request :)
class ActiveModel::Errors
def full_message(attribute, message)
return message if attribute == :base
attr_name = attribute.to_s.tr('.', '_').humanize
attr_name = @base.class.human_attribute_name(attribute, :default => attr_name)
I18n.t(:"errors.formats.attributes.#{attribute}", {
:default => [:"errors.format","%{attribute} %{message}"],
:attribute => attr_name,
:message => message
})
end
end
And add following to your locale file:
en:
errors:
formats:
attributes:
name: '%{message}'
Upvotes: 0
Reputation: 1373
I know this question is old. But just for reference in case someone else stumbles over it as I just did.
At least in Rails 3.0.x (not sure about earlier versions) you can use the leading ^ as indicated by RadBrad without the need for any gems/plugins.
Upvotes: 17
Reputation: 31467
I've found this answer more useable:
validate uniqueness amongst multiple subclasses with Single Table Inheritance
Upvotes: 0
Reputation: 1484
I too had the same issue with RoR 3.0.3. I couldn't find a way to display the validation messages without the name of the attributes. The code that Swards posted earlier didn't work for me, but it was a good start.
I placed the following code in an RB file in the config/initializers folders:
ActiveModel::Errors.class_eval do
# Remove complicated logic
def full_messages
full_messages = []
each do |attribute, messages|
messages = Array.wrap(messages)
next if messages.empty?
if attribute == :base
messages.each {|m| full_messages << m }
else
attr_name = attribute.to_s.gsub('.', '_').humanize
attr_name = @base.class.human_attribute_name(
attribute,
:default => attr_name
)
options = { :default => "%{message}", :attribute => attr_name }
messages.each do |m|
full_messages << I18n.t(:"errors.format", options.merge(:message => m))
end
end
end
full_messages
end
end
This removes the name of the attributes from all messages, which is exactly what I wanted to do.
Upvotes: 0
Reputation: 2005
Why not simply use the @object.errors hash ?!
Change the messages as you with in the validate part:
validates_uniqueness_of :foobar, :message => "The foobar isn't unique."
And then,
@foo.errors.to_a
You get a nice array where the second entry is the error message itself.
Upvotes: 1
Reputation: 12814
the link to rubyforge doesn't work, here is the custom error message plugin on github:
http://github.com/gumayunov/custom-err-msg
Upvotes: 1
Reputation: 18080
This is the best explanation I could find.
http://adamhooper.com/eng/articles/5
Essentially, in an initializer, change the full_messages method in ActiveRecord.Errors to return full sentences (not column_name, message concatenations) if you give a :message attribute in the validation.
Update - If you try Adam's code, you have to use the en.yml property file, if not it won't work as expected. You can either do this or get around it by modifying the full_messages method further. This works for me. I added the following to an initializer (/imitializers/active_record_errors.rb)
if RAILS_GEM_VERSION =~ /^2\.3/
ActiveRecord::Errors.class_eval do
# Remove complicated logic
def full_messages
returning full_messages = [] do
@errors.each_key do |attr|
@errors[attr].each do |message|
next unless message
if attr == "base"
full_messages << message
elsif message =~ /^\^/
full_messages << $' #' Grabs the text after the '^'
else
attr_name = @base.class.human_attribute_name(attr)
full_messages << attr_name + I18n.t('activerecord.errors.format.separator', :default => ' ') + message
end
end
end
end
end
end
end
Adam also makes good arguments for modifying Rails to support this for internationalization efforts.
Upvotes: 3
Reputation: 31464
The way that I did this was override ALL the messages, and not use the Rails form helpers for displaying error messages.
This seems like a lot of work, but it actually has some nice benefits. You get full control of the message, and then you can implement a custom form builder that can put the error messages inline, which is nicer for the user.
You use it like this:
validates_uniqueness_of :foobar, :message => "The foobar isn't unique."
Then don't use full_messages
when printing the error message.
Upvotes: 1