Why Doesn't Rails' "Errors.Full_Messages" Replace Attribute and Message Variables

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



Leave a reply



Submit