# Handling Create and Update Operations with Turbo Streams in Rails 7 (rspec tests included)

## TL;DR

```ruby
post searches_url, params: { search: invalid_attributes }, as: :turbo_stream
```

---

I have recently implemented CRUD(Create, Read, Update, Delete) operations using Rails 7. There are multiple methodologies for creating and updating records. One such method involves the deactivation of Turbo within the form. Consider the following example:

```ruby
<%= form_with model: search, html: { data: { turbo: false } } do |f| %>
<% end %>
```

Following this configuration in your form, your controller can respond either with an HTML format or redirect upon successful operation completion.

An alternative method for creating and updating records involves the use of turbo\_stream for handling failure responses. Rails 7 defaults to the turbo\_stream format the form submissions. Consequently, it's essential that your controller responds in the turbo\_stream format as well.  

Here is my implementation of this:

```ruby
def create # rubocop:disable Metrics/AbcSize
    result = Searches::Create.new(current_user:, params: search_params).call
    if result.success?
      redirect_to search_url(result.success[:search]), notice: 'Wyszukiwanie zostało utworzone.'
    else
      flash.now[:error] = result.failure[:message]
      render 'searches/update', locals: { search: result.failure[:search] }
    end
  end
```

In the instance of failure, the 'searches/update' template, a turbo\_stream extension, is rendered. The corresponding file for this extension is 'update.turbo\_stream.erb' In this file, I update both the form and flash components:

```ruby
# app/views/searches/update.turbo_stream.erb
<%= turbo_stream.replace(search, partial: 'searches/form', locals: { search: }) %>
<%= turbo_stream.update('flashes_component') do %>
  <%= render FlashesComponent.new(flash: flash, position: 'bottom-right') %>
<% end %>
```

## Tests

To thoroughly test these requests, I created tests for both HTML and turbo\_stream formats. Here's how you can test a request with an HTML format:

```ruby
context 'with invalid parameters' do
    it 'renders a new template' do
        post searches_url, params: { search: invalid_attributes }
        expect(response).to render_template('searches/update')
        expect(response.body).to include('Nie udało się utworzyć wyszukiwania. Popraw dane w formularzu.')
    end
end
```

In contrast, to test the turbo\_stream format, you'll need to send the request in the corresponding format:

```ruby
post searches_url, params: { search: invalid_attributes }, as: :turbo_stream
```

These implementation and testing strategies should equip you well for setting up your CRUD operations in Rails 7.

Lastly, I've included a GIF to visually demonstrate how errors are handled using turbo\_stream.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1684683083520/32ad1339-a93e-48a5-b6fd-1ce610560fb2.gif align="center")
