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'
を追加します。
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モデルを編集していきます。
class Post < ApplicationRecord
has_rich_text :content
end
モデルの編集はこの一行だけです。
Controllerの編集
post_paramsでcontent許可する為以下を追記します。
def post_params
params.require(:post).permit(:title, :content)
end
Viewの編集
リッチテキストを追加/参照できるようにViewを編集します。
<div class="field">
<%= form.label :content %>
<%= form.rich_text_field :content %>
</div>
rich_text_field
というActionTextで追加されたメソッドの記述でリッチテキストが使用できるようになります。
<%= @post.content %>
実際に画面を見てみる
データベースにはどのように保存されているのか
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つのテーブルを見ていきます。
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> 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> 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」を試してみた