【问题标题】:How to display validation errors when using nested forms?使用嵌套表单时如何显示验证错误?
【发布时间】:2014-04-29 19:39:02
【问题描述】:

首先对我的英语和我对 Rails 的了解感到抱歉,我是刚开始的初学者。

我有 2 个有关系的模型:

货物项目:

class CargoItem < ActiveRecord::Base
  belongs_to :cargo
  attr_accessible :cargo_id, :height, :length, :pieces, :weight, :width
  validates :cargo, :height, :length, :width, :weight, :pieces, presence: true
  validates :height, :length, :width, :pieces, numericality: { only_integer: true, greater_than_or_equal_to: 1}
  validates :weight, numericality: { only_integer: true, greater_than_or_equal_to: 100}
end

货物:

class Cargo < ActiveRecord::Base
  belongs_to :airport
  belongs_to :user
  belongs_to :cargo_state
  belongs_to :cargo_price
  belongs_to :cargo_description
  has_many :cargo_items, :inverse_of => :cargo, :dependent => :destroy

  attr_accessible :departure_date, :cargo_state_id, :airport_id, :cargo_price_id, :cargo_description_id, :cargo_items_attributes
  accepts_nested_attributes_for :cargo_items, :allow_destroy => true, :reject_if => :all_blank
  validates_associated :cargo_items
  validates :departure_date, :cargo_state, :airport, :cargo_price, :cargo_description, presence: true
  validates :departure_date, date: { after: Proc.new { Date.today - 1.day }, before: Proc.new { Time.now + 1.year } }, :on => :create
  default_scope :order => 'departure_date DESC'
end

我使用以下 GEM:simple_forms、nested_forms。这是使用属于 Cargos 的多个 CargoItems(它们有可能被动态添加)添加新 Cargo 的形式:

<%= simple_nested_form_for @cargo, :wrapper => false do |f| %>
<%= f.association :airport, :label_method => :full_airport_name, :value_method => :id , :order => :iata_code %>
<%= f.input :departure_date , as: :date, start_year: Date.today.year,
end_year: Date.today.year + 16,
order: [:day, :month, :year] %>
<%= f.association :cargo_description, :label_method => :description, :value_method => :id, :order => :description %>
<%= f.association :cargo_price, :label_method => :price, :value_method => :id %>
<%= f.association :cargo_state, :label_method => :state, :value_method => :id %>
<hr>
<table>
    <tr>
        <th><%= :length %></th>
        <th><%= :width %></th>
        <th><%= :height %></th>
        <th><%= :weight %></th>
        <th><%= :pieces %></th>
    </tr>
    <%= f.simple_fields_for :cargo_items, @cargo_item do |cargo_items_fields| %>
    <tr class="fields">
        <td><%= cargo_items_fields.text_field :length %></td>
        <td><%= cargo_items_fields.text_field :width %></td>
        <td><%= cargo_items_fields.text_field :height %></td>
        <td><%= cargo_items_fields.text_field :weight %></td>
        <td><%= cargo_items_fields.text_field :pieces %></td>
        <td><%= cargo_items_fields.link_to_remove "Remove this item", :confirm => 'Are you sure you want to remove this item?' %></td>
    </tr>
    <% end %>
</table>
<%= f.link_to_add "Add a item", :cargo_items %>

<div class="actions">
    <%= f.button :submit %>
</div>
<% end %>

货物管制员:

  def new
    @cargo = Cargo.new
    @cargo_item = CargoItem.new

    respond_to do |format|
      format.html # new.html.erb
      format.json { render json: @cargo }
    end
  end

  def create
    @cargo = Cargo.new(params[:cargo])
    @cargo.user_id = current_user[:id]

    respond_to do |format|
      if @cargo.save
        format.html { redirect_to @cargo, notice: 'Cargo was successfully created.' }
        format.json { render json: @cargo, status: :created, location: @cargo }
      else
        format.html { render action: "new" }
        format.json { render json: @cargo.errors, status: :unprocessable_entity }
      end
    end
  end

我的问题是,CargoItems 没有显示验证错误,模型实际上正在验证。我无法使用不符合验证规则的 CargoItems 保存货物。但是如果没有满足验证,Cargo 不会保存,它只是停留在同一页面上,没有任何 CargoItems 字段无效的通知。货物字段验证错误正确显示。

非常感谢您对我的帮助。

【问题讨论】:

    标签: ruby-on-rails validation associations nested-forms


    【解决方案1】:

    您需要在表单之前添加此错误通知。以我的为例

    <% if @author.errors.any? %>
        <div class="alert alert-block">
            <ul>
                <% @author.errors.full_messages.each do |msg| %>
                    <li><%= msg %></li>
                <% end %>
            </ul>
        </div>
    <% end %>
    <% if @book.errors.any? %>
        <div class="alert alert-block">
            <ul>
                <% @book.errors.full_messages.each do |msg| %>
                    <li><%= msg %></li>
                <% end %>
            </ul>
        </div>
    <% end %>
    
    <%= form_for([@author, @book], html: { class: "well" }) do |f| %>
    #labels and buttons...
    <% end %>
    

    我有一个作者,他有很多书,就像这样:

    作者:

    class Author < ActiveRecord::Base
      attr_accessible :name
      has_many :books, dependent: :destroy
    
      accepts_nested_attributes_for :books, allow_destroy: true
    
      validates :name, presence: true
      validates :name, length: { minimum: 3 }
    end
    

    书:

    class Book < ActiveRecord::Base
      attr_accessible :name, :year
      belongs_to :author
    
      validates :name, :year, presence: true
      validates :year, numericality: { only_integer: true, less_than_or_equal_to: Time.now.year }
    end
    

    【讨论】:

    • 非常感谢您的帮助,它可以部分工作。它在表单顶部显示有问题的字段,但字段没有用颜色突出显示,因为它们处于 Cargo 的父表单中。是否有可能像简单的表单一样提供相同的通知(突出显示每个有问题的字段并在该字段旁边显示每个问题)?
    • 我添加了另一个答案,如果对您有帮助,请将其标记为已选中。
    • 嗨,我有时间检查这个提议的解决方案,它工作正常。你是对的,我没有在表单中包含第一部分“”。我只是希望,简单的表单将以与父表单相同的方式处理嵌套表单,其中 this !" 不需要构造。
    【解决方案2】:

    Simple Form 还允许您使用 label、hint、input_field、error 和 full_error 帮助器。更多详细文档 --> https://github.com/plataformatec/simple_form

    有错误的示例代码,

    <%= simple_form_for @user do |f| %>
      <%= f.label :username %>
      <%= f.input_field :username %>
      <%= f.hint 'No special characters, please!' %>
      <%= f.error :username, id: 'user_name_error' %>
      <%= f.full_error :token %>
      <%= f.submit 'Save' %>
    <% end %>
    

    【讨论】:

    • 对不起,我不明白这部分,您是否建议使用简单表单的“嵌套表单”功能,而不是嵌套表单 gem?我认为这对我没有帮助,只要我选择 Nested Forms gem 是因为它能够构建嵌套表单,并且可以逐个动态添加项目。我认为简单的表单无法做到这一点。
    • simple_nested_form_for 在字段错误方面与 simple_form_for 具有相同的功能
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-24
    • 2012-10-09
    • 1970-01-01
    • 1970-01-01
    • 2016-01-06
    相关资源
    最近更新 更多