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.