如何在交易中的多模态的形式显示错误消息? [英] How to display error messages in a multi-model form with transaction?

查看:168
本文介绍了如何在交易中的多模态的形式显示错误消息?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有两种型号,组织和用户,有一个1:一对多的关系。我有一个联合注册的形式,其中一个组织以及该组织的用户得到签署。

我遇到的问题是:当对用户提交无效信息时,它再次呈现形式,因为它应该,但对于用户的错误信息(例如用户名不能为空)是不显示。当有效的信息被提交的表单不工作,它显示错误信息的组织,只是没有用户。

我应该如何调整code以下,这样还可以得到显示用户错误信息?

 高清新
  @organization = Organization.new
  @user = @ organization.users.build
结束

DEF创建
  @organization = Organization.new(new_params.except(:users_attributes))#Validations要求用户之前保存的组织,因为用户需要ORGANIZATION_ID。这就是为什么users_attributs如上排除在外,为什么下面它的原因是,如果任何组织或用户无效回滚事务管理。这种工作方式所需。

  @ organization.transaction做
    如果@ organization.valid?
        @ organization.save
        开始
          #我执行的调试器下一行(与无效用户信息),它正确地响应:ActiveRecord的:: RecordInvalid异常:验证失败:电子邮件不能为空,电子邮件是无效的,用户名不能为空,等等。
          @ organization.users.create!(users_attributes)
        拯救
          #如果我也许需要添加的那一行,增加了用户错误的记忆?
          提高的ActiveRecord ::回滚
        结束
     结束
  结束

  如果@ organization.persisted?
    闪光[:成功=是啊!
    redirect_to时root_url
  其他
    @user = @ organization.users.build(users_attributes)#否则,填写资料的用户则消失了(用户字段,然后空)
    渲染:新
  结束

结束
 

该表单视图包括:

 <%=的form_for @organization,网址:next_url做| F | %>
    <%=渲染部分:共享/ error_messages,当地人:{对象:f.object,nested_models:f.object.users}%GT;
    <%= f.text_field:名称%>
        #其他领域

    <%= f.fields_for:用户做| P | %>
        <%= p.email_field:电子邮件%>
            #其他领域
    <%结束%GT;

    <%= f.submit提交%>
<%结束%GT;
 

的错误消息的部分如下:

 <%object.errors.full_messages.each办|味精| %>
  <李><%= msg.html_safe%>< /李>
<%结束%GT;
 

更新:继罗布的回答,我得出了下面的部分错误的步骤。这仍然不会为用户显示错误消息。我加了调试器的响应里面的code以下,由于某种原因 nested_model.errors.any?返回false,同时控制器内部的调试器(见上文),并返回错误消息用户。

 <%如果object.errors.any? %>
  < D​​IV ID =error_explanation>
    < D​​IV CLASS =警报警报的危险>
      该表格​​包含<%=复数(object.errors.count,错误)%取代。
    < / DIV>

    < UL>
      <%object.errors.full_messages.each办|味精| %>
        <李><%= msg.html_safe%>< /李>
      <%结束%GT;
    < / UL>

  < / DIV>
<%结束%GT;

<%如果定义(nested_models)及?&安培; nested_models.any? %>
  #调试器:用局部变量的回应和定义(nested_models)?nested_models.any?返回true。
  < D​​IV ID =error_explanation>
    < UL>
      <%nested_models.each办| nested_model | %>
      #调试器:nested_model有相同的价值观,你所期望的nested_models.any?。但对于nested_model.errors.any?它返回假的,它不应该。
        <%如果nested_model.errors.any? %> #Initially有除非nested_model.valid?但对于用户的错误会立即显示在加载窗体页(新方法)。
          < UL>
            <%nested_model.errors.full_messages.each办|味精| %>
              <李><%= msg.html_safe%>< /李>
            <%结束%GT;
          < / UL>
        <%结束%GT;
      <%结束%GT;
    < / UL>
  < / DIV>
<%结束%GT;
 

解决方案

看起来你有很多不可测的逻辑在控制器中。看起来像你的逻辑将是更好地使用简单FormObject模式。 https://robots.thoughtbot.com/activemodel-form-objects

Two models, Organization and User, have a 1:many relationship. I have a combined signup form where an organization plus a user for that organization get signed up.

The problem I'm experiencing is: When submitting invalid information for the user, it renders the form again, as it should, but the error messages (such as "username can't be blank") for the user are not displayed. The form does work when valid information is submitted and it does display error messages for organization, just not for user.

How should I adjust the code below so that also the error messages for user get displayed?

def new
  @organization = Organization.new
  @user = @organization.users.build
end

def create
  @organization = Organization.new(new_params.except(:users_attributes))    #Validations require the organization to be saved before user, since user requires an organization_id. That's why users_attributs are above excluded and why below it's managed in a transaction that rollbacks if either organization or user is invalid. This works as desired.

  @organization.transaction do
    if @organization.valid?
        @organization.save
        begin
          # I executed next line in debugger (with invalid user info), which correctly responds with: ActiveRecord::RecordInvalid Exception: Validation failed: Email can't be blank, Email is invalid, Username can't be blank, etc.
          @organization.users.create!(users_attributes)
        rescue
          # Should I perhaps add some line here that adds the users errors to the memory?
          raise ActiveRecord::Rollback
        end
     end
  end

  if @organization.persisted?
    flash[:success] = "Yeah!"
    redirect_to root_url
  else
    @user = @organization.users.build(users_attributes)  # Otherwise the filled in information for user is gone (fields for user are then empty)
    render :new
  end

end

The form view includes:

<%= form_for @organization, url: next_url do |f| %>
    <%= render partial: 'shared/error_messages', locals: { object: f.object, nested_models: f.object.users } %>
    <%= f.text_field :name %>
        # Other fields

    <%= f.fields_for :users do |p| %>
        <%= p.email_field :email %>
            # Other fields
    <% end %>

    <%= f.submit "Submit" %>
<% end %>

The error messages partial is as follows:

<% object.errors.full_messages.each do |msg| %>
  <li><%= msg.html_safe %></li>
<% end %>

Update: Following the steps from Rob's answer I arrived at the errors partial below. This still does not display error messages for User. I added debugger responses inside the code below and for some reason nested_model.errors.any? returns false, while the debugger inside the controller (see above) does return error messages for user.

<% if object.errors.any? %>
  <div id="error_explanation">
    <div class="alert alert-danger">
      The form contains <%= pluralize(object.errors.count, "error") %>.
    </div>

    <ul>
      <% object.errors.full_messages.each do |msg| %>
        <li><%= msg.html_safe %></li>
      <% end %>
    </ul>

  </div>
<% end %>

<% if defined?(nested_models) && nested_models.any? %>
  # Debugger: responds with "local-variable" for "defined?(nested_models)" and for "nested_models.any?" returns true.
  <div id="error_explanation">
    <ul>
      <% nested_models.each do |nested_model| %>
      # Debugger: "nested_model" has the same values as "nested_models.any?", as you would expect. But for "nested_model.errors.any?" it returns false, which it shouldn't.
        <% if nested_model.errors.any? %>    #Initially had "unless nested_model.valid?" but then errors for User are immediately displayed on loading the form page (new method).
          <ul>
            <% nested_model.errors.full_messages.each do |msg| %>
              <li><%= msg.html_safe %></li>
            <% end %>
          </ul>
        <% end %>
      <% end %>
    </ul>
  </div>
<% end %>

解决方案

Looks like you have a lot of untestable logic in your controller. Looks like for you logic will be better to use simple FormObject pattern. https://robots.thoughtbot.com/activemodel-form-objects

这篇关于如何在交易中的多模态的形式显示错误消息?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆