0

I am developing a 2-step booking form using turbo-rails in order to use Ajax and update only the necessary page components. I am using 2 models, BookingDate and Booking. BookingDate contains the start and end DateTimes. Booking contains the BookingDate and the other booking attributes. The application consists in a single page. The idea is this: after the user chooses the dates and presses Next Step, the app saves the BookingDate record, still displays the date pickers enabled (in edit mode), and shows the items available for those dates. The problem is: I am not able to display the editable date pickers after saving the dates. Instead, the app shows the booking_dates/index page.

views/cust/customer_bookings/_main.html.erb

<%= turbo_frame_tag @booking_date do %>
  <%= render "booking_dates/cust_form", booking_date: @booking_date %>
<% end %>

views/bookings_dates/_cust_form.html.erb

<%= turbo_frame_tag @booking_date do %>
  <%= simple_form_for(@booking_date) do |f| %>
    <%= f.date_field :start_date %>
    <%= f.date_field :end_date %>
    <%= f.submit value = "Next step" %>
<% end %>

controllers/booking_dates_controller.rb

  def create
    @booking_date = BookingDate.new(booking_date_params)
    respond_to do |format|
      if @booking_date.save
        format.html { render :edit, location: @booking_date }
        format.json { render :show, status: :created, location: @booking_date }
      else
        ...
      end
    end
  end

views/booking_dates/_edit.html.erb

<%= turbo_frame_tag @booking_date do %>
  <%= render "booking_dates/cust_form", booking_date: @booking_date %>
<% end %>

Server log:

Started POST "/booking_dates" for ::1 at 2023-02-27 18:53:58 +0100
Processing by BookingDatesController#create as TURBO_STREAM
...
app/controllers/booking_dates_controller.rb:46:in `block in create'
TRANSACTION (93.7ms)  commit transaction
↳ app/controllers/booking_dates_controller.rb:46:in `block in create'
Rendering booking_dates/edit.html.erb
Rendered booking_dates/_cust_form.html.erb (Duration: 3.2ms | Allocations: 1042)
Rendered booking_dates/edit.html.erb (Duration: 4.2ms | Allocations: 1217)
Completed 200 OK in 110ms (Views: 5.6ms | ActiveRecord: 94.5ms | Allocations: 4237)
Started GET "/booking_dates" for ::1 at 2023-02-27 09:17:18 +0100

For the use of turbo frames I am using this tutorial: Hotrails - Turbo Rails tutorial

perissf
  • 15,979
  • 14
  • 80
  • 117
  • 1
    You never render a body and send a `Location` header in the same response. What's the point of sending an entire page if you're also telling the client to redirect? – max Feb 27 '23 at 09:51
  • Aha, I misunderstood the location option, I thought it was used for sending the object to the next view, instead it's redirecting. However, after deleting the location option, the result looks the same – perissf Feb 27 '23 at 10:11
  • 1
    You may be thinking of `locals:` which is used to [pass local assigns to a view](https://guides.rubyonrails.org/layouts_and_rendering.html#passing-local-variables). – max Feb 27 '23 at 10:22
  • @max changed to `format.html { render partial: "cust_form", locals: {booking_date: @booking_date } }` . Apparently nothing is changing, the page redirects after saving, Adding the first part of the log – perissf Feb 27 '23 at 18:10
  • I don't think this is actually rendering the view that you think it is. `render :edit` will render `edit.html.erb` not `_edit.html.erb` which is a partial by convention. – max Feb 27 '23 at 22:05

1 Answers1

0

Solved by doing the following:

  1. As suggested in the comment, changed the controller's edit action to: format.html { render :edit, status: :ok, locals: {booking_date: @booking_date } }
  2. In edit.html.erb, changed the turbo_fram_tag to "new_booking_date". For me, this was the bug most difficult to spot: after persisting the object, the previous code turbo_frame_tag @booking_date was pointing to the persisted object, therefore breaking the logic of having a turbo frame with the same id "new_booking_date"
perissf
  • 15,979
  • 14
  • 80
  • 117