All threads / How do I pass local variables to iteration in turbo_stream?
Ask A Question

Notifications

You’re not receiving notifications from this thread.

How do I pass local variables to iteration in turbo_stream?

Gabriel asked in Ruby

In my app I have projects which have many tasks. The tasks are iterated through on the projects show page:

### Project#show 

 <% @tasks.each do |task| %>
    <tr class="cursor-pointer">
       <td class="px-6 pr-3 py-4 w-12">

         <%= form_with(...) do |form| %>
           <div id="task_checkbox_<%= task.id %>">
              <%= render partial: "projects/partials/task_checkbox", locals: { form: form, task: task } %>
           </div>
         <% end %>

       </td>
   </tr>
<% end %>

The Partial however has the regarding form element which is a radio button:

### Partial: projects/partials/_task_checkbox.html.erb

<%= form.label :done, value: false, class:"block whitespace-nowrap" do %>
<%= form.radio_button(:done, false, class:"hidden", onchange: "this.form.requestSubmit()") %>
  <p>Radio Button Label</p>
<% end %>

If i click the radio button within the iteration for tasks, the task switches it's state to done: true as expected. However the whole thing is tied to a turbo_stream:

### update.turbo_stream.erb -> Update action of tasks_controller

<%= turbo_stream.replace "task_checkbox" do %>
<%= render partial: "projects/partials/task_checkbox", locals: { form: form, task: task } %>
<% end %>
### tasks_controller.rb

 def update
    respond_to do |format|
      if @task.update(task_params)
        format.turbo_stream
        format.html { redirect_to task_url(@task), notice: "Task was successfully updated." }
        format.json { render :show, status: :ok, location: @task }
      else
        format.html { render :edit, status: :unprocessable_entity }
        format.json { render json: @task.errors, status: :unprocessable_entity }
      end
    end
  end

Since the partial is within the tasks iteration and a form, i pass two local variables form and task. However, updating the task to done: true returns an error for the turbo_stream unit as follows:

undefined local variable or method 'task'

I found this file within the turbo-rails rep (https://github.com/hotwired/turbo-rails/blob/main/app/models/turbo/streams/tag_builder.rb), which does not really help me, since the use case is different (i font want to replace the whole iteration but one field). Variations didn't work either so far.

How do I pass local variables through a turbo stream to a partial?

Join the discussion

Want to stay up-to-date with Ruby on Rails?

Join 68,326+ developers who get early access to new tutorials, screencasts, articles, and more.

    We care about the protection of your data. Read our Privacy Policy.

    logo Created with Sketch.

    Screencast tutorials to help you learn Ruby on Rails, Javascript, Hotwire, Turbo, Stimulus.js, PostgreSQL, MySQL, Ubuntu, and more. Icons by Icons8

    © 2022 GoRails, LLC. All rights reserved.