Updating a parent and child, when turbo frames are used

Hi folks

was wondering how you would handle this situation?

# quote.rb
has_many :line_items

#line_item.rb
belongs_to :quote
# line_items have a price attribute
<!––  quote.html.erb  ––>

@quote.line_items.sum(:price) # display total cost

line_items.each do |line_item|
   turbo_frame_tag line_item do
       render "line_item", line_item: line_item
                    # show line_item partial allows for
                    # editing within the same turbo_frame
  end
end

Example - let’s update a line item’s price. When we do so, the TOTAL is not changed, because the update occurs within the line_item turbo_frame, but the TOTAL variable is outside the turbo_frame. i.e. need to update values that are both INSIDE and outside a particular turbo_frame:

# quote.html.erb
# quotes/1  

Total: $10
Line Item price: 10  # (but let's edit and reduce the
                     #  line item price to 0)
# After refreshing the page - quote.html.erb
Total: $10 # this value should be 0
Line Item: $0 

notice how the quote total is not updated?

I was wondering what you all do, and how you manage when a total on parent model has to be updated, given that a child in a turbo-frame has been updated?

Not sure if this is making any sense?

Maybe you could render a turbo stream action that updates the total?

# quote.rb
def total
  line_items.map(&:price).reduce(&:+)
end
# _quote.html.erb
<div id="<%= dom_id(quote) %>_total">
  <%= "Total: #{ quote.total }" %>
</div>

<% quote.line_items.each do |line_item| %>
  <%= turbo_frame_tag line_item do %>
    <%= render "line_items/line_item", line_item: line_item %>
  <% end %>
<% end %>

# line_items/show.html.erb
<%= turbo_frame_tag @line_item do %>
 <turbo-stream action="update", target="<%= dom_id(@line_item.quote) %>_total">
    <template>
      <%= "Total: #{ @line_item.quote.total }" %>
    </template>
  </turbo-stream>

  <%= render @line_item %>
<% end %>

Looks very interesting! Thank you i will try this out :+1:

Actually, I changed and used streams instead of a frame. same templates can be used.