【问题标题】:Invalid Create Method Throws No Errors无效的创建方法不会引发错误
【发布时间】:2021-01-13 21:24:52
【问题描述】:

我有一个表格可以为地址簿创建新联系人。在模型中,first_name 和 last_name 字段是必需的:

models/contact.rb

class Contact < ApplicationRecord
  [...]
  validates :first_name, :last_name, presence: true
end

如果在创建新联系人时出现错误,我的代码应该会显示消息:

views/contacts/_form.html.erb

<%= form_with model: @contact do |form| %>

  <% if @contact.errors.any? %>
    <div id="error_explanation">
      <h2>
        <%= pluralize(@contact.errors.count, "error") %> prevented this contact from being saved:
      </h2>
      <ul>
        <% @contact.errors.full_messages.each do |msg| %>
          <li><%= msg %></li>
        <% end %>
      </ul>
    </div>
  <% end %>

  <p>
    <%= form.label :salutation %><br>
    <%= form.select :salutation, options_for_select([['Mr.'], ['Mrs.'], ['Ms.'], ['Mx']]), class: "form-control"  %><br>
    <%= form.label :first_name, "First Name*" %><br>
    <%= form.text_field :first_name, class: "form-control" %><br>
    <%= form.label :middle_name, "Middle Name" %><br>
    <%= form.text_field :middle_name, class: "form-control" %><br>
    <%= form.label :last_name, "Last Name*" %><br>
    <%= form.text_field :last_name, class: "form-control" %>
    [...]

当我输入缺少名字或姓氏的联系人时,不会创建联系人并且页面停留在表单上。但是,视图顶部不会出现任何错误。我在控制器中添加了一些调试,发现虽然提交无效,但没有产生错误:

controllers/contacts_controller.rb

[...]
 def create
    @contact = Contact.new(contact_params)
    logger.debug "New contact: #{@contact.attributes.inspect}"
    logger.debug "Contact should have errors: #{@contact.errors.any?}"
    logger.debug "Contact should be invalid: #{@contact.invalid?}"
[...]

这会在终端中产生以下响应:

Started POST "/contacts" for ::1 at 2020-09-28 11:42:47 +0200
Processing by ContactsController#create as JS
  Parameters: {"authenticity_token"=>"2GBdtJXn77B9+IQuXg03C9HFgMS+ayzqP5lke49HcsvcM02L6lgyoGXuOtKL72mBzNsFU6EawC2dU+mN6RZzkA==", "contact"=>{"salutation"=>"Mrs.", "first_name"=>"Sue", "middle_name"=>"", "last_name"=>"", "ssn"=>"", "dob"=>"", "comment"=>""}, "commit"=>"Create Contact"}
New contact: {"id"=>nil, "salutation"=>"Mrs.", "first_name"=>"Sue", "middle_name"=>"", "last_name"=>"", "ssn"=>"", "dob"=>"", "comment"=>"", "created_at"=>nil, "updated_at"=>nil}
Contact should have errors: false
Contact should be invalid: true
  Rendering contacts/new.html.erb within layouts/application
  Rendered contacts/_form.html.erb (Duration: 4.7ms | Allocations: 1484)
  Rendered contacts/new.html.erb within layouts/application (Duration: 5.0ms | Allocations: 1569)
[Webpacker] Everything's up-to-date. Nothing to do
Completed 200 OK in 70ms (Views: 20.1ms | ActiveRecord: 27.1ms | Allocations: 18926)

这对我来说很奇怪:联系人应该有错误:false;联系人应该是无效的:true 据我所知,我在模型中的验证是正确的,并且提交被认为是无效的,但是由于某种原因,这不会转化为错误。我需要改变什么?

任何帮助都会非常棒!感谢您的关注。

编辑:

这里是完整的 create 方法,包括 .save 方法:

def create
    @contact = Contact.new(contact_params)

    if @contact.save
      redirect_to @contact, notice: 'Contact was successfully created'
    else
      render 'new'
    end
  end

这是尝试提交无效请求后的网页图像:

network tab view with errors displayed

【问题讨论】:

  • 需要注意的是,验证“错误”和实际异常有很大的区别。验证失败不会引发异常,它只是在错误对象中添加一个条目,以防止对象被保存。只有当您使用“bang 方法”.save!.create! 时,Rails 才会在记录无效时引发 RecordNotValid 异常。

标签: ruby-on-rails validation error-handling


【解决方案1】:

Contact.new 初始化一个新的Contact 对象,但不验证或存储它。

致电valid?invalid? 进行验证。这会将错误添加到记录中。如果你在上面调用save(或save!),它也会在存储记录之前运行验证。

【讨论】:

  • 感谢您的回复,@Siim !我应该在我的原始帖子中包含完整的显示方法,但它确实包含对“.save”的调用[参见上面的更新]。我看到,如果我将调试移到 else 子句,现在会附加错误。这意味着问题可能出在@contact.errors.any?表单中的代码块,但我看不出问题可能是什么。当我查看网络选项卡时,它会显示一个附有错误的视图。您也可以在上面看到这张图片。
猜你喜欢
  • 1970-01-01
  • 2018-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多