Why doesn't Rails' errors.full_messages replace attribute and message variables?
Upgrading to Version rails 2.3.9 fixes this problem
gem install -v 2.3.9 rails --include-dependencies
EDIT:
You also need to edit the config\environment.rb
file to change the RAILS_GEM_VERSION
.
RAILS_GEM_VERSION = '2.3.9'
EDIT #2:
I should note that version 2.3.9 is not the latest version of the 2.3.X branch, and you should upgrade the the latest version available.
Rails 3 full error messages format
don't know if it can help, but a locale file for Bulgarian is available on Github.
you may also try this (should work according to rails guides):
bg:
errors:
format: "%{message}"
messages: &error_messages
empty: "Something something %{attribute} something something"
this blog post and this stack overflow issue also talk about weird {{attribute}} {{message}}
structures. Seems caused by a conflict between two I18n gems installed on the same server.
Ruby on rails. How to format errors.full_messages?
Solution:
s.errors.message[:upload_file_name]
I18n gem update causing error message crazyness in rails 2.3.8
See my answer to original question, Why doesn't Rails' "errors.full_messages" replace attribute and message variables?
rails error message displays key and I only want value
full_messages
method prepends attribute name
to the validation error message
.
Following is the method implementation in rails
## Following code is extracted from Rails source code
def full_messages
map { |attribute, message| full_message(attribute, message) }
end
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.format", {
default: "%{attribute} %{message}",
attribute: attr_name,
message: message
})
end
If you see the full_messages
method it in turn calls full_messages
wherein attribute gets prepended to the error message.
So, if you add attribute name
in the validation error message
it is definitely going to be duplicated which is what is happening in your case.
In nutshell, you don't need to specify attribute name in validation message, as rails is already taking care of it.
EDIT
Nothing is impossible. If you want you could customize it as below
<% if @profile.errors.any? %>
<ul>
<% @profile.errors.messages.each do |attr, msg| %>
<% msg.each do |val| %>
<li><%= val %></li>
<% end %>
<% end %>
</ul>
<% end %>
Rails 7 signup form doesn't show error messages
If you look at the logs you can see that Rails is getting an AJAX request in the form of a turbo stream:
Processing by UsersController#create as TURBO_STREAM
Where it should read:
Processing by UsersController#create as HTML
To disable turbo you want need to set a data-turbo="false"
attribute on the form:
<% provide(:title, 'Sign up') %>
<h1>Sign up</h1>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= form_with(model: @user, data: { turbo: false }) do |f| %>
<%= render 'shared/error_messages' %>
<%= f.label :name %>
<%= f.text_field :name, class: 'form-control' %>
<%= f.label :email %>
<%= f.email_field :email, class: 'form-control' %>
<%= f.label :password %>
<%= f.password_field :password, class: 'form-control' %>
<%= f.label :password_confirmation, "Confirmation" %>
<%= f.password_field :password_confirmation, class: 'form-control' %>
<%= f.submit "Create my account", class: "btn btn-primary" %>
<% end %>
</div>
</div>
The local: false
option only works with the old Rails UJS javascript library which was the default prior to Rails 7. You can also disable Turbo by default with:
import { Turbo } from "@hotwired/turbo-rails"
Turbo.session.drive = false
See:
https://turbo.hotwired.dev/handbook/drive#disabling-turbo-drive-on-specific-links-or-forms
Incorrect plural error messages with nested attributes
As @Marc suggested, the messages are generated based on the model. This gets tricky when accepts_nested_attributes_for
is involved, as it is in my Account model:
has_many :users, :inverse_of => :account, :dependent => :destroy
accepts_nested_attributes_for :users
To get more insight into the error object, I inserted <%= object.errors.inspect %>
into _error_messages.html.erb. This showed me that the full error object is, for example:
#<ActiveModel::Errors:0xb5c86a8 @base=#<Account id: nil, name: "", created_at: nil, updated_at: nil>,
@messages={:"users.password"=>["doesn't match confirmation", "is too
short (minimum is 8 characters)"], :name=>["can't be blank"]}>
When Rails generates the full_messages array, it just feeds each attribute and message into the full_message method. If the attribute is "users.password", for example, then that will simply be "humanized" (without respect to the number of objects in the array) and concatenated with the message(s) to return
Users password doesn't match confirmation
Users password is too short (minimum is 8 characters)
The crux of any solution is to avoid using full_messages:
Although I couldn't get
error_messages_for
to work, it wouldn't be too
hard to write a small helper that allows specifying a custom object
name to prepend to the message.Avoid the problem of the displaying object name altogether by highlighting the
specific field that is in error and placing the error message suffix(es) next
to the field. This works nicely with Twitter Bootstrap and SimpleForm.This article make a good case for providing explicit
translations for each message, claiming that any attempt to
concatenate strings is bound to cause problems.
Rails 4 validation message: removes _id from message
There are several "correct" ways to go about this, but you definitely shouldn't do it via the validation itself, or by defining your own validation method.
On a model-by-model level, this is controlled by the class-level human_attribute_name
method.
If you want your model's employee_id
field to be a special case where the _id
postfix isn't truncated, define that special case by overridding human_attribute_name
:
class MyModel
validates :employee_id, presence: true
def self.human_attribute_name(attr, options = {})
attr == :employee_id ? 'Employee ID' : super
end
end
In broader terms, you can redefine human_attribute_name
on ActiveRecord::Base
to override handling of all _id
attributes, but I doubt you want to do this. Generally, it's a good thing that Rails drops the _id
postfix.
The second (and probably better) mechanism is to simply rely on localization. ActiveRecord ties into your locale YAML files for just about everything. If you want your employee_id
field to humanize to Employee ID
regardless of language, you'll need to edit your YAML files.
# config/locales/en.yml
en:
activerecord:
attributes:
employee_id: "Employee ID"
Related Topics
Ruby - Dynamically Add Property to Class (At Runtime)
How to Determine the Md5 Digest of a Given Asset in the Rails Asset Pipeline
Migrating from Rails 2 to Rails 3
How to Resolve Rails Model Namespace Collision
Rails: Dynamic Columns/Attributes on Models
Micropost's Comments on Users Page (Ruby on Rails)
How to Sort in Ruby/Rails on Two Fields
Devise: How to Override Devise Error Messages on Password Change
Rendering a Partial from a Controller in Rails
Factorygirl Association Model Trouble: "Systemstackerror: Stack Level Too Deep"
Why Is Ruby Unable to Verify an Ssl Certificate
Naming Boolean Columns in Rails
How to Display a PDF in Ror (Ruby)
Passing Headers and Query Params in Httparty
How to Unfreeze an Object in Ruby
How to Get the Latest Record from Each Group in Activerecord
Rails: Opposite of Hash#To_Param
Options for Distribution of an Offline Ruby on Rails Application