All threads / Turbo Stream - dynamically replacing partial on the page

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?

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.

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.

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

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.

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.

Join the discussion

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

Join 48,387+ 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.

    Ruby on Rails tutorials, guides, and screencasts for web developers learning Ruby, Rails, Javascript, Turbolinks, Stimulus.js, Vue.js, and more. Icons by Icons8

    © 2021 GoRails, LLC. All rights reserved.