使用Rails 3.1.3。我有帐户和用户。一个帐户可以拥有多个用户。我按照this answer中的说明使用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不要复数?
<小时/> 修改3/14/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 %>
答案 0 :(得分:1)
这种情况正在发生,因为它是一个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)
享受!
答案 1 :(得分:0)
正如@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 。这向我展示了完整的错误对象,例如:
#&lt; ActiveModel :: Errors:0xb5c86a8 @base =#&lt; Account id:nil,name:“”,created_at:nil,updated_at:nil&gt;, @messages = {:“users.password”=&gt; [“与确认不符”,“也是 短(最少8个字符)“],:name =&gt; [”不能为空白“]}&gt;
当Rails生成full_messages数组时,它只会将每个属性和消息提供给full_message方法。例如,如果属性是“users.password”,那么它将只是“人性化”(不考虑数组中的对象数)并与消息连接以返回
用户密码与确认不符 用户密码太短(最少8个字符)
任何解决方案的关键是避免使用full_messages:
虽然我无法让error_messages_for
工作,但也不会
很难写一个允许指定自定义对象的小助手
名称预先添加到消息中。
通过突出显示来完全避免显示对象名称的问题 错误的特定字段,然后放置错误消息后缀 到了现场。这适用于Twitter Bootstrap和SimpleForm。
This article为提供明确提供了一个很好的理由 每条消息的翻译,声称任何尝试 连接字符串必然会导致问题。