Ask A Question

Notifications

You’re not receiving notifications from this thread.

Turbo Stream - dynamically replacing partial on the page

RJ McCollam asked in Rails

I have an edit user page that has multiple cards on it. I have each card wrapped in its own turbo frame tag with a unique id. On the update action in my controller if I just redirect_to @user the src attribute on the turbo frame does not update so I cannot click edit again to replace the frame.

Instead of redirecting I want to implement a format.turbo_stream. Rather than being able to replace a single partial I need to replace the one that was edited. To get this context I am including a partial name in the different form partials that is the partial name.

In creating an instance variable for that partial I was hoping I could use that in my update.turbo_stream.erb file. Like this:

<%= turbo_stream.replace "user_#{@partial}", partial: "users/display/#{@partial}" %>

In theory I think this will work, but since I am passing a param that is not part of the model it will not update my resource, and of course if I don't permit the param it gets rejected all together.

I have two questions:

  1. Am I missing a better way to update specific partials on an update action using turbo_steams?
  2. How can I get my partial parameter to come through in update action without trying to update my resource with it?
Reply

If you have the HTML ID in the URL (or sent as a param), you could use that in your turbo_stream.replace.

For example:

<% @cards.each do |card| %>
  <%= tag.div id: dom_id(card) %>
    <%= render partial: "cards/show", locals: { card: card } %>
  <% end %>
<% end %>
<%= turbo_stream.replace dom_id(card), partial: "cards/show" %>

That gives you a consistent ID across things.

Turbo Frames would expect you to have routes for the card show & edit and would handle this for you automatically as long as you had a resources :cards controller filled out with the matching frames.

Reply

This makes sense, but in this instance I don't have a consistent model that is being output. These cards as I call them are actually each for a different model. Each card houses my create form and lists each item from the module.

So on my turbo_stream.replace I am wanting to target a manually entered ID as each one is different. I do want to send it as a param in each form, but getting it accepted into my controller is where I am getting stuck.

Reply

You should be able to pass params or variables when calling turbo

<%= turbo_stream.replace "user_#{@partial}", partial: "users/display/#{@partial}", locals: {params: params, partial: @partial } %>

Reply
Reply

Thanks @ugurcan, that is how I planned on calling it. Again my main issue here is getting this value into my controller so I can pass it to my turbo_stream file.

Reply

Assuming you are posting to this controller using a form, params and other variables are already there and available in turbo stream file.

Pass all saved variables to the partial and replace old one.

Reply
Join the discussion
Create an account Log in

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

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

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

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

    © 2024 GoRails, LLC. All rights reserved.