Turbo Stream - dynamically replacing partial on the page
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:
- Am I missing a better way to update specific partials on an update action using turbo_steams?
- 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.