验证和渲染期间的问题

Issue during validation and render

我在提交表单时遇到问题。

我有两个模型,: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 in Bookings#create
undefined method title

我也会得到错误:

undefined method price

和:

undefined method 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

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

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

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

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

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