ActiveRecord validation messages are currently not I18N-friendly. Specifically, I'm referring to the fact that it enforces a certain grammar, namely the beginning of the message must consist of the field name. For example:
validates_presence_of :name, :message => "can't be blank."
...generates the message "Name can't be blank". This grammar works in English, but may not work in other languages.
Furthermore, such messages are not always appropriate even in English. Suppose I want the message to be "Please enter your name". I can't. Right now I work around this by writing my own show_errors() view helper method (an alternative for error_messages_on()), which only shows the ':message' part of the errors (i.e. without the field part). In my models I then write:
validates_presence_of :name, :message => "Please enter your name."
Or, suppose I'm making an application that's only in Dutch. I put this in my models:
validates_presence_of :name, :message => "Voer a.u.b. uw naam in."
This mostly works, but some plugins, such as attachment_fu, add their own validation rules to models (such as 'validates_presence_of :size'). If I use my show_errors() method then I can get messages like this:
* Please enter your name. * can't be blank. <--- ouch! the field name is omitted
It's interesting to note Ruby-Gettext allows one to change the grammar by allowing one to set the position of the field name, like this:
validates_presence_of :name, :message => "Please enter your %{fn}."
There had been discussions in the past on how to properly support I18N in Rails, and people can't seem to reach to a consensus. I would like to propose a solution which solves the grammar issue, thereby making validation messages at least a little more I18N-friendly. This solution is minimal and does not enforce any particular full-blown I18N solution on the developer, and should be backwards compatible. The proposal is as follows:
If the :message argument is given to a validates_whatever, then check whether the :message string contains "%{fn}". If so, then the full validation error message should be formatted using the :message string, like this:
full_message = message.sub('%{fn}', human_attribute_name)
If no "%{fn}" is given, then it should check whether the following is true:
message.chars.capitalize == message
If so, then the full validation error message should equal that of the message argument. This allows one to specify a full sentence in the :message parameter, without ActiveRecord::Errors automatically prepending the field name. If the message is not in a western language, e.g. Chinese, then the above expression should return true. Since in these languages it is always inappropriate to prepend the (English) database attribute name, using the verbatim message as given by the message argument would be the correct behavior.
If none of the above 2 conditions are true, then the full validation error message should be generated in the same way as the current way.
Examples:
validates_presence_of :name # => "Name can't be blank" validates_presence_of :name, :message => "must be given" # => "Name must be given." validates_presence_of :name, :message => "Please enter your name." # => "Please enter your name." validates_presence_of :name, :message => "请你写你的名字。" # => "请你写你的名 字。"