【问题标题】:Issue during validation and render验证和渲染期间的问题
【发布时间】:2016-12-08 02:27:33
【问题描述】:

提交表单时遇到问题。

我有两个模型,:service:booking。对于服务,有一个按钮:

<%= link_to "Book Now", new_booking_path(service_id: @service.id) %>

点击此按钮后,用户将转到_form.html.erb,在那里他们可以预订服务。这是简化的预订表格:

<%= simple_form_for (@booking) do |f| %>

    <%= f.label "Booking Date" %><br>
    <%= f.text_field :date %>
    <%= f.text_field :time, :id => "timepicker" %>
    <%= f.input :address, label: "Address" %>
    <%= f.input :postcode, label: "Postcode" %>
    <%= f.input :suburb, label: "Suburb" %>

    <%= f.input :servicetitle, :input_html => { :value => @service.title } %>
    <%= f.input :serviceprice, :input_html => { :value => @service.price } %>
    <%= f.input :servicetime, :input_html =>  { :value => @service.time } %>

    <%= f.button :submit %>
<% end %>

如您所见,我有三个字段,:servicetitle:serviceprice:servicetime

这些字段从通过 link_to 按钮传递的 @service.id 值获取其输入值。我可以使用bookings_controller 中的这个实例变量来访问像@service.title 这样的记录:

@service = Service.find_by_id(params[:service_id])

我遇到的问题是,如果其中一个字段验证失败(比如:date 字段),那么用户会被重定向回_form.html.erb,我会收到错误

预订中的 NoMethodError#create
未定义方法title

我也会得到错误:

未定义的方法price

和:

未定义的方法time

我认为这是因为 Rails 无法再访问 @service 实例变量了?

验证失败时如何解决此问题?

编辑

在预订控制器中创建方法:

def create
    @booking = current_user.bookings.build(bookings_params)
    if @booking.save
        BookingMailer.form_confirmation(@booking).deliver
        redirect_to @booking
    else
        render 'new'
    end
end

【问题讨论】:

  • 预订相关的服务如何实施?输入字段是什么?
  • @vee 一个服务属于一个预订,一个预订有很多服务。我的表单工作正常,除非它在错误时呈现表单,@service 实例变量似乎被破坏了
  • 对,您的 create 方法没有定义 @service 这就是您丢失值的原因。您可以发布您的控制器create 操作吗?
  • @vee 用 create 方法更新了我的问题
  • 您是否让您的用户在预订期间创建服务?您是否更愿意使用可用服务的“选择选项”/下拉列表,以便您可以轻松地在BookingsController#create 中唯一地标识您的服务。这是 Rails 5 吗?

标签: ruby-on-rails validation simple-form


【解决方案1】:

我很确定这是因为在您的 create 方法中您没有为 @service 变量分配任何东西,在您的新方法中您正在实例化 @service 变量(至少我假设您是当您转到“操作”时没有收到错误),但您没有在创建操作中执行此操作。

当您执行创建操作时,整个请求周期将从头开始,这意味着您在“新建”操作中所做的任何事情都已消失。 当您遇到错误时,您的创建操作会转到 else 块并运行 render 'new' 从头开始​​渲染 new.html.erb 模板,如果您正在渲染带有 @service 变量的模板,那么您需要在渲染模板之前的操作。例如@service = Service.new@service = Service.find(params[:service_id])。否则,您的模板将调用 nil 对象上的 title pricetime 方法。

【讨论】:

  • 谢谢,是的,我明白发生了什么,尽管即使我在创建方法中包含 @service = Service.find(params[:service_id]) 行,我仍然会收到错误
  • 完全相同的错误?您可以发布设置@service时遇到的错误,以及设置@service的create方法中的代码,以及发送创建请求时的日志
【解决方案2】:

您还没有再次将服务 ID 传递给 create 方法,因此它可能不会在 create 中获取 params[:service_id]。

在表单中添加一个带有 service_id 的隐藏字段,然后检查。

<%= hidden_field_tag(:service_id,@service.id) %>

【讨论】:

  • 我不敢相信,但这确实有效!非常感谢。
猜你喜欢
  • 2020-08-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-07
  • 2014-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多