When the action PATCH /contracts/:id/kill is triggered from the index view we do not want to be redirect to the contract show, as usual, but instead stay in the index view and just UPDATE the contract card.
Add a turbo-frame around the contract card
#app/views/contracts/_contract.html.erb
<%= turbo_frame_tag contract do%>
[code for the contract card]
<%end%>
HTML generated ⬇️
<turbo-frame id="contract_31" style="outline: rgb(186, 38, 139) dashed 2px;">
[code for the contract card]
</turbo-frame>
As you can see when passing an AR object Turbo will generate a name based on the model and the object ID. (you can manually name the Frame ⇒ turbo_frame_tag “frame_name”)

And that’s it!! The turbo Magic will do the rest
When clicking on + to add a new contract, it triggers GET /contracts/new, we want the form to be insert, just above the contracts list.

Add a turbo-frame tag in the the new view, turbo_frame_tag "new_contract"
# app/views/contracts/new.html.erb
[...]
<h1 class="mb-4">Congrats You get a new Contrat</h1>
<%= turbo_frame_tag "new_contract" do%>
<%= render 'form',contract: Contract.new %>
<% end %>
[...]
HTML generated ⬇️
[...]
<h1 class="mb-4">Congrats You get a new Contrat</h1>
<turbo-frame id="new_contract">
[code from *form* partial]
</turbo-frame>
[...]

As we are not targeting the same TurboFrame, we need to specify the target name in the link using data attribute data-turbo-frame ="new_contract"
# app/views/contracts/index.html.erb
[...]
<%= link_to new_contract_path, data:{turbo_frame: "new_contract"} do%>
<i class="fa-solid fa-circle-plus text-black"></i>
<% end %>
[...]
For create and destroy actions, the contract card is modified.
We will use the turbo-stream action to modify our list
Add a new turbo-frame tag around the list

# app/views/contracts/index.html.erb
<%= turbo_frame_tag "contracts" do%>
<% @contracts.each do |contract| %>
<%= turbo_frame_tag contract, src:"/contracts/#{contract.id}", loading:"lazy" do%>
LOADING
<%#= render 'contracts/contract', contract: contract %>
<% end %>
<% end %>
<% end %>
Let’s modify the controller and create the turbo_stream view. Now the controller will have to render based on the request format :
app/views/contracts/create.turbo_frame.erb def create
@contract = Contract.new(contract_params)
@contract.save
respond_to do |format|
flash.now[:notice] = "A new target has been added"
format.html { redirect_to contract_path(@contract) }
format.turbo_stream
end
end
Add the create.turbo_frame.erb
# app/views/contracts/create.turbo_frame.erb
<%= turbo_stream.prepend "contracts", @contract %>
<%#prepend the turbo-frame id="contracts with the render of the partial _contract
with contract=@contract"%>
<%= turbo_stream.replace "new_contract" do %>
<%= turbo_frame_tag "new_contract" %>
<%end%>
<%# replace the turbo-frame id="new_contract" AKA the form frame, by an empty turbo-frame
"new_contract"%>
List of turbo action