【図解】Hotwire : Turbo 7つのアクション

# はじめに
チュートリアルでHotwireの基本を学んだ後に、Railsアプリでサンプルページを作りながら、Turboで用意されてる7つのアクションについて動作確認した結果を図にしました。

各アクションのサンプルコードも本ページに記載しておりますので、Turboの学習にお役立ていただけたらと思います。

## ざっくり見たい方向け
![all-20220314.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141934/e4e3b200-2a52-2c8a-e610-d473436395ad.png)


## 公式ドキュメント
[Turbo Reference](https://turbo.hotwired.dev/reference/streams)


# アクション

- Append / Prepend
- Replace
- Update
- Remove
- Before / After

## append
`append`は指定したTurboFrameの中の最後に要素を追加します。

### 図解
![append.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141934/cd82b39d-195d-64e6-a0ab-a71cdc86a7f3.png)

### サンプルコード（Rails：抜粋）
ユーザ一覧の最後にユーザを追加。

```ruby:users_controller.rb
def index
  @users = User.first(3)
end
def append
  @users = User.last(3)
  render layout: false, content_type: 'text/vnd.turbo-stream.html'
end
```

```erb:index.html.erb
<%= turbo_frame_tag 'users' do %>
 <% @users.each do |user| %>
    <div id="<%= dom_id user %>"><%= user.name %></div>
  <% end %>
<% end %>
<%= turbo_frame_tag 'append' do %>
  <%= link_to 'append', append_path %>
<% end %>
```

```erb:append.html.erb
<%= turbo_stream.append "users" do %>
  <% @users.each do |user| %>
    <div id="<%= dom_id user %>"><%= user.name %></div>
  <% end %>
<% end  %>
```

## prepend
`prepend`は指定したTurboFrameの中の先頭に要素を追加します。

### 図解
![prepend.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141934/8531cd72-b48a-4e4b-9b92-b592bfdd07fe.png)

### サンプルコード（Rails：抜粋）
ユーザ一覧の先頭にユーザを追加。

```ruby:users_controller.rb
def index
  @users = User.first(3)
end
def prepend
  @users = User.last(3)
  render layout: false, content_type: 'text/vnd.turbo-stream.html'
end
```

```erb:index.html.erb
<%= turbo_frame_tag 'users' do %>
 <% @users.each do |user| %>
    <div id="<%= dom_id user %>"><%= user.name %></div>
  <% end %>
<% end %>
<%= turbo_frame_tag 'prepend' do %>
  <%= link_to 'prepend', prepend_path %>
<% end %>
```

```erb:prepend.html.erb
<%= turbo_stream.prepend "users" do %>
  <% @users.each do |user| %>
    <div id="<%= dom_id user %>"><%= user.name %></div>
  <% end %>
<% end  %>
```

## replace
`replace`は指定したTurboFrameを上書きします。

### 図解
![replace.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141934/0f7e091f-617d-be13-cdf2-58e9b8ffb3ad.png)

### サンプルコード（Rails：抜粋）
ユーザ一覧をアイテム一覧に置き換える。

```ruby:users_controller.rb
def index
  @users = User.first(3)
end
def replace
  @items = Item.last(3)
  render layout: false, content_type: 'text/vnd.turbo-stream.html'
end
```

```erb:index.html.erb
<%= turbo_frame_tag 'users' do %>
 <% @users.each do |user| %>
    <div id="<%= dom_id user %>"><%= user.name %></div>
  <% end %>
<% end %>
<%= turbo_frame_tag 'replace' do %>
  <%= link_to 'replace', replace_path %>
<% end %>
```

```erb:replace.html.erb
<%= turbo_stream.replace "users" do %>
  <%= turbo_frame_tag 'items' do %>
    <% @items.each do |item| %>
      <div id="<%= dom_id item %>"><%= item.name %></div>
    <% end %>
  <% end %>
<% end  %>
```

## update
`update`は指定したTurboFrameの内容を更新します。

### 図解
![update.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141934/f1689815-d3ac-c8b4-4387-985d02a2a527.png)

### サンプルコード（Rails：抜粋）
ユーザ一覧を更新。

```ruby:users_controller.rb
def index
  @users = User.first(3)
end
def update
  @users = User.last(3)
  render layout: false, content_type: 'text/vnd.turbo-stream.html'
end
```

```erb:index.html.erb
<%= turbo_frame_tag 'users' do %>
 <% @users.each do |user| %>
    <div id="<%= dom_id user %>"><%= user.name %></div>
  <% end %>
<% end %>
<%= turbo_frame_tag 'update' do %>
  <%= link_to 'update', update_path %>
<% end %>
```


```erb:update.html.erb
<%= turbo_stream.update "users" do %>
  <% @users.each do |user| %>
    <div id="<%= dom_id user %>"><%= user.name %></div>
  <% end %>
<% end  %>
```

## remove
`remove`は指定したTurboFrameを取り除きます。

### 図解
![remove.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141934/c1fe19af-5383-7529-e6f0-a572845dcf5d.png)

### サンプルコード（Rails：抜粋）
ユーザ一覧を削除

```ruby:users_controller.rb
def index
  @users = User.first(3)
end
def remove
  render layout: false, content_type: 'text/vnd.turbo-stream.html'
end
```

```erb:index.html.erb
<%= turbo_frame_tag 'users' do %>
 <% @users.each do |user| %>
    <div id="<%= dom_id user %>"><%= user.name %></div>
  <% end %>
<% end %>
<%= turbo_frame_tag 'remove' do %>
  <%= link_to 'remove', remove_path %>
<% end %>
```

```erb:remove.html.erb
<%= turbo_stream.remove "users" %>
```

## before
`before`は指定したTurboFrameの前に要素を追加します。

### 図解
![before.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141934/d821036b-2af7-ecf9-f3b7-2bd96cb21544.png)

### サンプルコード（Rails：抜粋）
ユーザ一覧の前にアイテム一覧を追加。

```ruby:users_controller.rb
def index
  @users = User.first(3)
end
def before
  @items = Item.last(3)
  render layout: false, content_type: 'text/vnd.turbo-stream.html'
end
```

```erb:index.html.erb
<%= turbo_frame_tag 'users' do %>
 <% @users.each do |user| %>
    <div id="<%= dom_id user %>"><%= user.name %></div>
  <% end %>
<% end %>
<%= turbo_frame_tag 'before' do %>
  <%= link_to 'before', before_path %>
<% end %>
```

```erb:before.html.erb
<%= turbo_stream.before "users" do %>
  <%= turbo_frame_tag 'items' do %>
    <% @items.each do |item| %>
      <div id="<%= dom_id item %>"><%= item.name %></div>
    <% end %>
  <% end %>
<% end  %>
```


## after
`after`は指定したTurboFrameの後に要素を追加します。

### 図解
![after.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141934/1597cec1-2eca-309a-9a98-c88d0cea1df3.png)

### サンプルコード（Rails：抜粋）
ユーザ一覧の後ろにアイテム一覧を追加。


```ruby:users_controller.rb
def index
  @users = User.first(3)
end
def after
  @items = Item.last(3)
  render layout: false, content_type: 'text/vnd.turbo-stream.html'
end
```

```erb:index.html.erb
<%= turbo_frame_tag 'users' do %>
 <% @users.each do |user| %>
    <div id="<%= dom_id user %>"><%= user.name %></div>
  <% end %>
<% end %>
<%= turbo_frame_tag 'after' do %>
  <%= link_to 'after', after_path %>
<% end %>
```

```erb:after.html.erb
<%= turbo_stream.after "users" do %>
  <%= turbo_frame_tag 'items' do %>
    <% @items.each do |item| %>
      <div id="<%= dom_id item %>"><%= item.name %></div>
    <% end %>
  <% end %>
<% end  %>
```