Updating Associated Models in Rails with Turbo Frames

I’m working on a Ruby on Rails 7 application with Turbo Frames, and I’ve encountered a design dilemma involving two models, Invoice and Customer. In my setup, the Invoice edit view includes a Turbo Frame (using turbo_frame_tag{src=“/customers?invoice_id=123”}) that displays the Customer#index view, complete with a “Select” button for each customer (if invoice.customer is nil).

Here’s the challenge: when a user selects a Customer, I’m currently handling this by submitting a form to invoices#update, where i update the @invoice.customer. However, I then want to update the Turbo Frame to show customer#show for the selected customer. This approach feels awkward because it involves rendering a Customer view from the InvoicesController. (or re-rendering my entire invoice/_form but this overwrites potential non-saved text inputs)

I’ve also considered updating the invoice.customer within the CustomersController#update action, but this doesn’t feel right either, as it involves modifying the Invoice from within the CustomersController.

I’m seeking advice on a more appropriate or Rails-idiomatic way to handle this. How can I efficiently and cleanly manage the interaction between these two models and update the views accordingly, while adhering to good MVC principles? Is there a better pattern or strategy for handling this kind of interaction between models and views, particularly in the context of Turbo Frames in Rails?

i prefer to do it without Stimulus; Turbo Streams is maybe an option; adding an additional function/method to my InvoicesController feels also like repeating the update code :frowning:

How would you solve this probem?

I’m currently handling this by submitting a form to invoices#update, where i update the @invoice.customer. However, I then want to update the Turbo Frame to show customer#show for the selected customer. This approach feels awkward because it involves rendering a Customer view from the InvoicesController.

It’s fine. You could create an independent controller, say InvoicingController, whose sole purpose is to associate a user with an invoice and render the resulting frame update you want there.

I would leave it as-is until you find a new need that causes you to revisit refactoring this.

Definitely not in CustomersController.

And, this sounds like a TurboFrame use case, not streams or Stimulus.