Help us understand the problem. What is going on with this article?

Rails6新機能 ActionText使用方法

ActionTextとは

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

ActionTextの導入方法

早速こちらのDHHの紹介動画を参考に試していきたいと思います。

アプリケーション作成

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

 $ rails new blog
 $ cd blog

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

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

 $ brew install imagemagick

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

ActionTextをインストール

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

Gemfile
gem 'actiontext'
- # gem 'image_processing', '~> 1.2'
gem 'image_processing', '~> 1.2'

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

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

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

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モデルのを作成し、マイグレーションを行います。

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

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

  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モデルを編集していきます。

post.rb
  class Post < ApplicationRecord
    has_rich_text :content
  end

モデルの編集はこの一行だけです。

Controllerの編集

post_paramsでcontent許可する為以下を追記します。

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

Viewの編集

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

posts/_form.html.erb
  <div class="field">
    <%= form.label :content %>
    <%= form.rich_text_field :content %>
  </div>

rich_text_fieldというActionTextで追加されたメソッドの記述でリッチテキストが使用できるようになります。

posts/show.html.erb
  <%= @post.content %>

実際に画面を見てみる

実際に画面をを見てみるとリッチテキストが表示されています。
スクリーンショット 2019-08-07 4.31.36.png

画像の登録もできます。
スクリーンショット 2019-08-07 4.36.13.png

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

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

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つのテーブルを見ていきます。

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_idPostの対象レコードIDが保存されています。

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_attachmentsaction_text_rich_textsとの関連情報が保存されるようです。なので、active_storage_attachmentsテーブルには1レコードしか存在しません。

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 の概要
ゼロから10分でブログが作れる!Rails 6の新機能「Action Text」を試してみた

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした