user6806935
user6806935

Reputation:

Issue during validation and render

I have an issue when submitting a form.

I have two models, :service and :booking. For a service, there is a button:

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

When this button is clicked it takes the user to the _form.html.erb where they can book the service. This is the simplified booking form:

<%= 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 %>

As you can see, I have three fields, :servicetitle, :serviceprice and :servicetime.

These fields get their input values from the @service.id value passed through the link_to button. I am able to access the records like @service.title using this instance variable in the bookings_controller:

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

The problem I am having is that if one of the field validation fails (say the :date field), then the user gets redirected back to the _form.html.erb and I get the error

NoMethodError in Bookings#create
undefined method title

I would also get the errors:

undefined method price

and:

undefined method time

I think this is because Rails doesn't have access to the @service instance variable anymore?

How am I able to fix this when a validation fails?

Edit:

Create method in bookings controller:

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

Upvotes: 0

Views: 60

Answers (2)

Ajit
Ajit

Reputation: 18

You haven't passed the service id again to create method so probably it won't be getting the params[:service_id] in create.

Add a hidden field in form with the service_id and then check.

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

Upvotes: 0

John Hayes-Reed
John Hayes-Reed

Reputation: 1428

I am pretty sure this is down to the fact that in your create method you have not assigned anything to the @service variable, in your new method you are instantiating the @service variable (at least I assume you are as you are not getting an error when you go to the 'action'), but you are not doing it in the create action.

When you go to the create action, the whole request cycle starts from scratch, meaning anything you did in the 'new' action is gone. When you have an error, your create action goes to the else block and runs render 'new' which renders the new.html.erb template from scratch, if you are rendering a template with an @service variable, then you will need to define that variable in the action before you render the template. eg @service = Service.new or @service = Service.find(params[:service_id]). Otherwise, your template is calling the title price and time methods on a nil object.

Upvotes: 1

Related Questions