Rails6新機能 ActionText使用方法

# ActionTextとは
`ActionTextはRails6の新機能の1つです。Railsにリッチテキストコンテンツと編集機能を簡単に導入できます。`

# ActionTextの導入方法
早速こちらの[DHHの紹介動画](https://www.youtube.com/watch?v=HJZ9TnKrt7Q&feature=youtu.be)を参考に試していきたいと思います。

## アプリケーション作成
紹介動画と同じようにBlogアプリケーションを作成しました。
そして、作成したBlogアプリケーションディレクトリーに移動します。

```terminal
 $ rails new blog
 $ cd blog
```
Rails6の新規アプリケーションでは`webpackerのgemがデフォルトでインストールされています。`

作成途中で気づいたのですが事前に`imagemagick`をインストールする必要があります。

```terminal
 $ brew install imagemagick
```
`imagemagick`をインストールしていないと画像の表示ができなかったです。

## ActionTextをインストール
ActionTextをインストールする為にGemfileに`gem 'actiontext'`とコメントアウトされている`# gem 'image_processing', '~> 1.2'`を追加します。

```ruby:Gemfile
gem 'actiontext'
- # gem 'image_processing', '~> 1.2'
gem 'image_processing', '~> 1.2'
```

`bundle install`を行い、ActionTextをインストールします。

```console
 $ bundle install
 $ bundle exec bin/rails action_text:install
```

すると、以下のファイルが作成されます。

```console
app/assets/stylesheets/actiontext.scss
test/fixtures/action_text/rich_texts.yml
app/views/active_storage/blobs/_blob.html.erb
20190806033549_create_active_storage_tables.active_storage.rb from active_storage
20190806033550_create_action_text_tables.action_text.rb from action_text
```

scaffoldで記事を投稿するPostモデルのを作成し、マイグレーションを行います。

```console
 $ bundle exec bin/rails g scaffold post title:string
 $ bundle exec bin/rails db:create db:migrate
```

postsテーブルの他に3つのテーブルが作成されています。

```ruby
  create_table "action_text_rich_texts", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
    t.string "name", null: false
    t.text "body", size: :long
    t.string "record_type", null: false
    t.bigint "record_id", null: false
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.index ["record_type", "record_id", "name"], name: "index_action_text_rich_texts_uniqueness", unique: true
  end

  create_table "active_storage_attachments", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
    t.string "name", null: false
    t.string "record_type", null: false
    t.bigint "record_id", null: false
    t.bigint "blob_id", null: false
    t.datetime "created_at", null: false
    t.index ["blob_id"], name: "index_active_storage_attachments_on_blob_id"
    t.index ["record_type", "record_id", "name", "blob_id"], name: "index_active_storage_attachments_uniqueness", unique: true
  end

  create_table "active_storage_blobs", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
    t.string "key", null: false
    t.string "filename", null: false
    t.string "content_type"
    t.text "metadata"
    t.bigint "byte_size", null: false
    t.string "checksum", null: false
    t.datetime "created_at", null: false
    t.index ["key"], name: "index_active_storage_blobs_on_key", unique: true
  end
```

## Modelの編集
リッチテキストを追加できるようにPostモデルを編集していきます。

```ruby:post.rb
  class Post < ApplicationRecord
    has_rich_text :content
  end
```
モデルの編集はこの一行だけです。

## Controllerの編集
post_paramsでcontent許可する為以下を追記します。

```ruby:posts_controller.rb
    def post_params
      params.require(:post).permit(:title, :content)
    end
```

## Viewの編集
リッチテキストを追加/参照できるようにViewを編集します。

```ruby:posts/_form.html.erb
  <div class="field">
    <%= form.label :content %>
    <%= form.rich_text_field :content %>
  </div>
```
`rich_text_field`というActionTextで追加されたメソッドの記述でリッチテキストが使用できるようになります。

```ruby:posts/show.html.erb
  <%= @post.content %>
```
## 実際に画面を見てみる
実際に画面をを見てみるとリッチテキストが表示されています。
<img width="534" alt="スクリーンショット 2019-08-07 4.31.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459450/6e60cf2c-deb8-b1df-83ca-48b79ddbd799.png">

画像の登録もできます。
<img width="537" alt="スクリーンショット 2019-08-07 4.36.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459450/56230ab4-ef3f-a288-166d-64f227d5bc9f.png">

# データベースにはどのように保存されているのか

postsテーブルを見てみると、保存されているのはtitileのみでpostsテーブルの中には投稿の内容は保存されていません。

```mysql
mysql> select * from posts;
+----+---------------------+----------------------------+----------------------------+
| id | title               | created_at                 | updated_at                 |
+----+---------------------+----------------------------+----------------------------+
|  3 | ActionText初投稿    | 2019-08-06 19:39:52.405346 | 2019-08-06 20:19:43.135677 |
+----+---------------------+----------------------------+----------------------------+
1 row in set (0.00 sec)
```

ActionTextをインストールした際に作成された3つのテーブルを見ていきます。



```mysql:action_text_rich_texts
mysql> select * from action_text_rich_texts;
+----+---------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------+-----------+----------------------------+----------------------------+
| id | name    | body                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       | record_type | record_id | created_at                 | updated_at                 |
+----+---------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------+-----------+----------------------------+----------------------------+
|  3 | content | <div><strong>ActionText初投稿！！！<br></strong><br></div><ul><li>ActionText</li><li>ActionText</li></ul><div><br></div><div><del>ActionText<br>ActionText</del></div><div><br><strong>画像も投稿！！</strong><br><action-text-attachment sgid="BAh7CEkiCGdpZAY6BkVUSSIwZ2lkOi8vYmxvZy9BY3RpdmVTdG9yYWdlOjpCbG9iLzQ_ZXhwaXJlc19pbgY7AFRJIgxwdXJwb3NlBjsAVEkiD2F0dGFjaGFibGUGOwBUSSIPZXhwaXJlc19hdAY7AFQw--d04d3371f0f9b2b295cfd66103c6406732424549" content-type="image/jpeg" url="http://localhost:3000/rails/active_storage/blobs/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBDUT09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--912629fe993490146ed666997ac8bb64a1275d7b/hanabi.jpg" filename="hanabi.jpg" filesize="112214" width="670" height="443" previewable="true" presentation="gallery"></action-text-attachment><br><br></div>                  | Post        |         3 | 2019-08-06 19:39:52.456662 | 2019-08-06 20:19:43.086752 |
+----+---------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------+-----------+----------------------------+----------------------------+
1 row in set (0.01 sec)
```
上記のテーブルの`body`に先ほど投稿した内容が保存されています。そして、`record_type`に`対象ModelのPost`が、`record_id`に`Postの対象レコードIDが保存されています。`


```mysql:active_storage_blobs
mysql> select * from active_storage_blobs;
+----+------------------------------+----------------------------------------------------+--------------+--------------------------------------------------------------+-----------+--------------------------+---------------------+
| id | key                          | filename                                           | content_type | metadata                                                     | byte_size | checksum                 | created_at          |
+----+------------------------------+----------------------------------------------------+--------------+--------------------------------------------------------------+-----------+--------------------------+---------------------+
|  1 | z4m2mtny2jvj2ljo0m8gakoqkmy5 | 漢-a.k.a.-GAMI.jpg                                 | image/jpeg   | NULL                                                         |     79598 | 07kFe+ahdZWyK/zmeJHllQ== | 2019-08-06 05:42:22 |
|  4 | gppnsrfhsww5cs8txslrg6u9h90t | hanabi.jpg                                         | image/jpeg   | {"identified":true,"width":670,"height":443,"analyzed":true} |    112214 | OrPese01Y/vGUZtnKejpgg== | 2019-08-06 19:35:14 |
|  5 | ugkzqy63bg6ejct4vwi8y9hgo296 | スクリーンショット 2019-08-07 4.31.36.png          | image/png    | NULL                                                         |     65984 | fYqXNtKywvvLZekT5iebMQ== | 2019-08-06 20:47:17 |
+----+------------------------------+----------------------------------------------------+--------------+--------------------------------------------------------------+-----------+--------------------------+---------------------+
3 rows in set (0.00 sec)
```
上記のテーブル、`active_storage_blobs`にアップロードした画像が保存されています。1枚の画像しか投稿していないのに画像レコードが3つもあります。これは、`画像をアップロードした時点で active_storage_blobs に新規レコードが作成されるようです。`

そして、投稿を完了（save)した時に`active_storage_attachments`に`action_text_rich_texts`との関連情報が保存されるようです。なので、`active_storage_attachments`テーブルには1レコードしか存在しません。

```mysql:active_storage_attachments
mysql> select * from active_storage_attachments;
+----+--------+----------------------+-----------+---------+---------------------+
| id | name   | record_type          | record_id | blob_id | created_at          |
+----+--------+----------------------+-----------+---------+---------------------+
|  3 | embeds | ActionText::RichText |         3 |       4 | 2019-08-06 19:39:52 |
+----+--------+----------------------+-----------+---------+---------------------+
1 row in set (0.00 sec)
```

# まとめ
ここまでRails6新機能ActionTextを試してきましたが、リッチテキストが本当に簡単に実装できることが分かりました。ただ、業務上で使うには画像のリサイズはどのようにするのか等の懸念点が多いのでもう少し詰めて行き見極めていきたいと思います。

# 参考
[Action Text の概要](https://railsguides.jp/action_text_overview.html)
[ゼロから10分でブログが作れる！Rails 6の新機能「Action Text」を試してみた](https://tech.libinc.co.jp/entry/rails6_action_text)