Неправильные множественные сообщения об ошибках с вложенными атрибутами - PullRequest
2 голосов
/ 08 февраля 2012

Использование Rails 3.1.3. У меня есть аккаунты и пользователи. Одна учетная запись может иметь много пользователей. Я настроил это, используя accepts_nested_attributes_for, как описано в этот ответ .

У меня есть представление new.html.erb, которое принимает данные для одной учетной записи и одного пользователя одновременно. (Данные пользователя переходят в «подчиненную форму».) Форма работает нормально. Однако, если есть ошибка, сообщения для полей подчиненной формы являются множественными, даже если они должны быть единичными. Например, я получаю

Users password doesn't match confirmation
Users password is too short (minimum is 8 characters)

вместо

User password doesn't match confirmation
User password is too short (minimum is 8 characters)

Я не думаю, что это проблема перегиба, поскольку «Пользователь» следует стандартным правилам множественного числа. Скорее это должно быть связано с использованием вложенных атрибутов в подчиненной форме. В моем случае подчиненная форма возвращает массив, содержащий одного пользователя, но теоретически она может возвращать данные для нескольких пользователей.

Как / где я могу сказать Rails не использовать множественное число при обращении только к одному элементу массива?

<ч /> Отредактировать 14.03.2012, чтобы показать контроллер и просмотреть:

app / controllers / accounts_controller.rb (только «Новое» действие):

class AccountsController < ApplicationController
  before_filter :authenticate_user!, :except => [:new, :create]
  before_filter :user_signed_out,    :only   => [:new, :create]
  load_and_authorize_resource # CanCan - does a standard load for each action, and authorizes user

  def new
    # CanCan:  @account = Account.new (and tests each attribute for ability)
    @account.users.build
    @title = "Sign Up for a New Account"
    @header = "Sign up for a new account"
  end
end

приложение / просмотров / счета / new.html.erb

<h2><%= @header %></h2>

<%= form_for(@account) do |f| %>
  <%= render 'account_fields', :f => f %>

  <%= f.fields_for :users do |user_form| %>
    <div class="field"><%= user_form.label :email %><br />
    <%= user_form.email_field :email %></div>
    <div class="field"><%= user_form.label :password %><br />
    <%= user_form.password_field :password %></div>
    <div class="field"><%= user_form.label :password_confirmation %><br />
    <%= user_form.password_field :password_confirmation %></div>
  <% end %>

  <div class="actions">
    <%= f.submit "Create Account" %>
  </div>
<% end %>

Я пытался error_messages_for внутри блока f.fields_for выше.

app / views / shared / _error_messages.html.erb отрисовано макетом перед всеми представлениями:

<% if object.errors.any? %>
  <div id="error_explanation">
    <h2><%= pluralize(object.errors.count, "error") %> 
      prohibited this <%= object.class.to_s.underscore.humanize.downcase %>
      from being saved:</h2>
    <p>There were problems with the following fields:</p>
    <ul>
    <% object.errors.full_messages.each do |msg| %>
      <li><%= msg %></li>
    <% end %>
    </ul>
  </div>
<% end %>

Ответы [ 2 ]

1 голос
/ 13 марта 2012

Это происходит потому, что это has_many ассоциация. Чтобы переопределить имя объекта, которое вы отображаете, вы можете передать эту опцию следующим образом:

<%= error_messages_for @account, :object => [@account, :users], :object_name => 'Account' %>

Это позволяет вам изменить этот ярлык на что угодно, например:

<%= error_messages_for @account, :object => [@account, :users], :object_name => 'Profile' %>

Что тогда будет выглядеть

Profile password doesn't match confirmation
Profile password is too short (minimum is 8 characters)

Наслаждайтесь!

0 голосов
/ 20 марта 2012

Как предположил @Marc, сообщения генерируются на основе модели.Это сложно, когда задействовано accepts_nested_attributes_for, как в моей модели учетной записи:

has_many :users, :inverse_of => :account, :dependent => :destroy
accepts_nested_attributes_for :users

Чтобы получить более полное представление об объекте ошибки, я вставил <%= object.errors.inspect %> в _error_messages.html.erb.Это показало мне, что полный объект ошибки, например:

#, @messages = {: "users.password" => ["не соответствует подтверждению", "слишком короткое (минимум 8 символов)"],: name => ["не может быть пустым"]}>

Когда Rails генерирует массив full_messages , он просто передает каждый атрибут и сообщение в метод full_message .Например, если атрибут «users.password», то он будет просто «гуманизирован» (без учета количества объектов в массиве) и объединен с сообщением (сообщениями), возвращающими

Пароль пользователя не соответствует подтверждению
Пароль пользователя слишком короткий (минимум 8 символов)

Суть любого решения - избегать использования full_messages:

  • Хотя я не смог заставить error_messages_for работать, было бы не сложно написать небольшой помощник, позволяющий указать произвольное имя объекта для добавления к сообщению.

  • Избегайте проблемы с отображением имени объекта в целом, выделив конкретное поле, в котором произошла ошибка, и поместив суффикс (и) сообщения об ошибке рядом с полем.Это прекрасно работает с Twitter Bootstrap и SimpleForm.

  • Эта статья дает хороший пример для предоставления явных переводов для каждого сообщения, утверждая, что любая попытка объединить строки является связаннойвызвать проблемы.

...