Railsガイドにきちんと目を通して新しい知識を得る - Action Text の概要編 -

ドキュメントを読み込むのは大事、ということでRailsガイドを頭から読んでいく取り組みをしています。 各章ごとに、(Railsガイドにちゃんと書いてあるのに)知らなかった機能を雑にまとめていきます。

今回は、Action Text の概要の章です。

railsguides.jp

summernoteを使ったことはありますが、ActionTextをinstallからしたことはなかったので勉強になりました。

リッチテキストコンテンツの作成

リンクはこちら

ActionTextをインストールさえしてしまえばとりあえず使うのは簡単です。
Modelファイルに以下を追記すれば良いです。

has_rich_text :xxx

ActionTextのインストール後にマイグレーションを実行すればaction_text_rich_textsテーブルが作成され、そこに保存されるので別途カラムを用意する必要もないです。

ちなみに、action_text_rich_textsは以下のような感じでした。

ID name body record_type record_id created_at updated_at
2 note <div><em>こんにちは</em></div> Book 2 ... ...

なお、添付ファイルがある場合はbodyの部分が以下のように保存されます。
action-text-attachment要素にsgid属性を付与するかたちになっています。

<div>
  <action-text-attachment sgid="xxx" content-type="image/png" url="http://localhost:3000/rails/active_storage/blobs/redirect/xxx/icon16.png" filename="icon16.png" filesize="62112" width="340" height="454" presentation="gallery">
  </action-text-attachment>
  <strong>こんにちは</strong>
</div>

N+1回避

リンクはこちら

添付ファイルなしの本文をまとめて取得するケースはwith_rich_text_xxxを使えます。
発行されるSQLは以下の通りで、action_text_rich_textからまとめて関連レコードを読み込んでくれていることがわかります。

Book.all.with_rich_text_note
# SELECT "books".* FROM "books"

# SELECT "action_text_rich_texts".* FROM "action_text_rich_texts"
# WHERE "action_text_rich_texts"."record_type" = $1
# AND "action_text_rich_texts"."name" = $2
# AND "action_text_rich_texts"."record_id"
# IN ($3, $4, $5, $6)  
# [["record_type", "Book"], ["name", "note"], ["record_id", 1], ["record_id", 2], ["record_id", 3], ["record_id", 4]]

添付ファイルを含めて読み込む場合は、with_rich_text_content_and_embedsを使います。
発行されるSQLを見ても、添付ファイルの情報も読み込んでいることがわかります。

Book.all.with_rich_text_note_and_embeds
# SELECT "books".* FROM "books"
# SELECT "action_text_rich_texts".* FROM "action_text_rich_texts" ...

# SELECT "active_storage_attachments".* FROM "active_storage_attachments"
# WHERE "active_storage_attachments"."record_type" = $1
# AND "active_storage_attachments"."name" = $2
# AND "active_storage_attachments"."record_id" IN ($3, $4, $5, $6) 
# [["record_type", "ActionText::RichText"], ["name", "embeds"], ["record_id", 1], ["record_id", 2], ["record_id", 3], ["record_id", 4]]

# SELECT "active_storage_blobs".* FROM "active_storage_blobs"
# WHERE "active_storage_blobs"."id" IN ($1, $2, $3)  [["id", 1], ["id", 3], ["id", 4]]