I am confused why i dont get 2 entries when i create a new quote with the following code.
My thought is that i would get an entry from the following:
- the create method that returns the turbo_stream and renders the create.turbo_stream
- the actionCable that im subscribed to.
if i remove the stream, i still get just 1 entry. if i remove the append method in create.turbo_stream, i still get one entry ( from the cable)
WHY DONT I GET 2 with both enabled?
controller:
In create i have a response type of format.turbo_stream.erb
along with the html response type.
create.turbo_stream.erb:
<%= turbo_stream.prepend "quotes", @quote %>
<%= turbo_stream.update Quote.new, "" %>
View
<%= turbo_stream_from( [current_company, "quotes"] ) %>
Quote model broadcast:
broadcasts_to ->(quote) { [quote.company, "quotes"] }, inserts_by: :prepend
CodePudding user response:
You've skipped the important part, the partial that you're rendering:
# app/views/quotes/_quote.html.erb
<div id="<%= dom_id(quote) %>">
<%= quote.content %>
</div>
Both of these:
turbo_stream.prepend "quotes", @quote
broadcasts_to ->(quote) { [quote.company, "quotes"] }, inserts_by: :prepend
eventually render a turbo_stream_action_tag that uses the _quote partial as a template:
<turbo-stream action="prepend" target="quotes">
<template>
<div id="quote_1"> q1 </div>
</template>
</turbo-stream>
On the front end, turbo
processes that tag and prepends the template to the specified target #quotes
:
<div id="quotes">
<div id="quote_1"> q1 </div>
</div>
Turbo prepend
and append
actions take the id
of direct child nodes into account and replace them instead.
If you want to get duplicates, just wrap everything in a tag:
# app/views/quotes/_quote.html.erb
<div>
<div id="<%= dom_id(quote) %>">
<%= quote.content %>
</div>
</div>
However, doing that will mess up the replace
action by forever nesting div
.
If the template’s first element has an id that is already used by a direct child inside the container targeted by dom_id, it is replaced instead of prepended.