edge
詳細はrubyonrails.orgで: もっとRuby on Rails

Action Textの概要

このガイドでは、リッチテキストコンテンツの処理を始めるために必要なすべての情報を提供します。

このガイドを読み終えると、以下のことがわかります。

1 Action Textとは?

Action Textは、リッチテキストコンテンツと編集をRailsにもたらします。それには、フォーマットからリンク、引用、リスト、埋め込み画像やギャラリーまで、すべてを処理するTrixエディタが含まれています。Trixエディタによって生成されるリッチテキストコンテンツは、既存のActive Recordモデルと関連付けられた独自のRichTextモデルに保存されます。埋め込み画像(またはその他の添付ファイル)は、Active Storageを使用して自動的に保存され、含まれるRichTextモデルと関連付けられます。

2 Trixと他のリッチテキストエディタの比較

ほとんどのWYSIWYGエディタは、HTMLのcontenteditableexecCommandのAPIをラップしたもので、これはMicrosoftがInternet Explorer 5.5でウェブページのライブ編集をサポートするために設計したものであり、後に他のブラウザによって逆にエンジニアリングされ、コピーされました。

これらのAPIは完全に指定されたり文書化されたりしなかったため、WYSIWYG HTMLエディタは非常に広範なスコープを持っており、各ブラウザの実装には独自のバグやクセがあります。そのため、JavaScript開発者はこれらの不一致を解決する必要があります。

Trixは、contenteditableをI/Oデバイスとして扱うことで、これらの不一致を回避しています。入力がエディタに届くと、Trixはその入力を内部ドキュメントモデル上の編集操作に変換し、そのドキュメントをエディタに再レンダリングします。これにより、Trixは各キーストロークの後に何が起こるかを完全に制御し、execCommandを使用する必要がなくなります。

3 インストール

bin/rails action_text:installを実行して、Yarnパッケージを追加し、必要なマイグレーションをコピーします。また、埋め込み画像やその他の添付ファイルにActive Storageを設定する必要があります。Active Storageの概要ガイドを参照してください。

注意:Action Textは、action_text_rich_textsテーブルとの多態関連を使用しているため、リッチテキスト属性を持つすべてのモデルで共有できます。Action Textコンテンツを使用するモデルが識別子としてUUID値を使用している場合、Action Text属性を使用するすべてのモデルも一意の識別子としてUUID値を使用する必要があります。Action Textの生成されたマイグレーションも、:record references行に対してtype: :uuidを指定するように更新する必要があります。

インストールが完了したら、Railsアプリには以下の変更が加えられます。

  1. JavaScriptのエントリーポイントでtrix@rails/actiontextの両方を要求する必要があります。

    // application.js
    import "trix"
    import "@rails/actiontext"
    
  2. trixのスタイルシートは、application.cssファイルに含まれるAction Textのスタイルと一緒に含まれます。

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

既存のモデルにリッチテキストフィールドを追加します。

# app/models/message.rb
class Message < ApplicationRecord
  has_rich_text :content
end

または、次のコマンドを使用して新しいモデルを作成しながらリッチテキストフィールドを追加します。

$ bin/rails generate model Message content:rich_text

注意:messagesテーブルにcontentフィールドを追加する必要はありません。

その後、モデルのフォームでこのフィールドを参照するためにrich_text_areaを使用します。

<%# app/views/messages/_form.html.erb %>
<%= form_with model: message do |form| %>
  <div class="field">
    <%= form.label :content %>
    <%= form.rich_text_area :content %>
  </div>
<% end %>

最後に、ページ上でサニタイズされたリッチテキストを表示します。

<%= @message.content %>

注意:contentフィールド内に添付されたリソースがある場合、マシンにlibvips/libvips42パッケージがインストールされていない限り、正しく表示されない場合があります。インストール方法については、インストールドキュメントを参照してください。

リッチテキストコンテンツを受け入れるために必要なのは、参照される属性を許可するだけです。

class MessagesController < ApplicationController
  def create
    message = Message.create! params.require(:message).permit(:title, :content)
    redirect_to message
  end
end

5 リッチテキストコンテンツのレンダリング

デフォルトでは、Action Textはリッチテキストコンテンツを.trix-contentクラスの要素内にレンダリングします。

<%# app/views/layouts/action_text/contents/_content.html.erb %>
<div class="trix-content">
  <%= yield %>
</div>

このクラスを持つ要素とAction Textエディタは、trixのスタイルシートによってスタイルが適用されます。代わりに独自のスタイルを提供する場合は、インストーラによって作成されたapp/assets/stylesheets/actiontext.cssスタイルシートからrequire trixの行を削除してください。

リッチテキストコンテンツの周りにレンダリングされるHTMLをカスタマイズするには、インストーラによって作成されたapp/views/layouts/action_text/contents/_content.html.erbレイアウトを編集します。

埋め込み画像やその他の添付ファイル(blobとも呼ばれます)のためにレンダリングされるHTMLをカスタマイズするには、インストーラによって作成されたapp/views/active_storage/blobs/_blob.html.erbテンプレートを編集します。

5.1 添付ファイルのレンダリング

Active Storageを介してアップロードされた添付ファイルに加えて、Action Textは署名付きGlobalIDで解決できるものを埋め込むことができます。

Action Textは埋め込まれた<action-text-attachment>要素を、そのsgid属性をインスタンスに解決することでレンダリングします。解決されたインスタンスは、renderに渡されます。その結果のHTMLは、<action-text-attachment>要素の子孫として埋め込まれます。

例えば、Userモデルを考えてみましょう:

# app/models/user.rb
class User < ApplicationRecord
  has_one_attached :avatar
end

user = User.find(1)
user.to_global_id.to_s #=> gid://MyRailsApp/User/1
user.to_signed_global_id.to_s #=> BAh7CEkiCG…

次に、Userインスタンスの署名付きGlobalIDを参照する<action-text-attachment>要素を埋め込むリッチテキストのコンテンツを考えてみましょう:

<p>Hello, <action-text-attachment sgid="BAh7CEkiCG…"></action-text-attachment>.</p>

Action Textは"BAh7CEkiCG…"という文字列を使用してUserインスタンスを解決します。次に、アプリケーションのusers/userパーシャルを考えてみましょう:

<%# app/views/users/_user.html.erb %>
<span><%= image_tag user.avatar %> <%= user.name %></span>

Action Textによってレンダリングされた結果のHTMLは、次のようになります:

<p>Hello, <action-text-attachment sgid="BAh7CEkiCG…"><span><img src="..."> Jane Doe</span></action-text-attachment>.</p>

異なるパーシャルをレンダリングするには、User#to_attachable_partial_pathを定義します:

class User < ApplicationRecord
  def to_attachable_partial_path
    "users/attachable"
  end
end

そして、そのパーシャルを宣言します。Userインスタンスはuserパーシャルローカル変数として利用できます:

<%# app/views/users/_attachable.html.erb %>
<span><%= image_tag user.avatar %> <%= user.name %></span>

Userインスタンスを解決できない場合(例えば、レコードが削除された場合)、デフォルトのフォールバックパーシャルがレンダリングされます。

Railsは、添付ファイルが見つからない場合のためのグローバルなパーシャルを提供しています。このパーシャルは、アプリケーションのviews/action_text/attachables/missing_attachableにインストールされ、異なるHTMLをレンダリングしたい場合に変更することができます。

異なる見つからない添付ファイルのパーシャルをレンダリングするには、クラスレベルのto_missing_attachable_partial_pathメソッドを定義します:

class User < ApplicationRecord
  def self.to_missing_attachable_partial_path
    "users/missing_attachable"
  end
end

そして、そのパーシャルを宣言します。

<%# app/views/users/missing_attachable.html.erb %>
<span>削除されたユーザー</span>

Action Textの<action-text-attachment>要素のレンダリングと統合するためには、クラスは次のようにする必要があります:

  • ActionText::Attachableモジュールを含める
  • GlobalID::Identification concernを介して利用可能な#to_sgid(**options)を実装する
  • (オプション)#to_attachable_partial_pathを宣言する
  • (オプション)欠落したレコードを処理するためのクラスレベルの#to_missing_attachable_partial_pathメソッドを宣言する

デフォルトでは、すべてのActiveRecord::Baseの子孫はGlobalID::Identification concernをミックスインしており、したがってActionText::Attachableと互換性があります。

6 N+1クエリを回避する

リッチテキストのフィールドがcontentという名前の場合、依存するActionText::RichTextモデルを事前にロードしたい場合は、次のような名前付きスコープを使用できます:

Message.all.with_rich_text_content # 添付ファイルなしで本文を事前にロードします。
Message.all.with_rich_text_content_and_embeds # 本文と添付ファイルの両方を事前にロードします。

7 API / バックエンド開発

  1. バックエンドAPI(例:JSONを使用)は、ActiveStorage::Blobを作成し、そのattachable_sgidを返す別のエンドポイントが必要です:

    {
      "attachable_sgid": "BAh7CEkiCG…"
    }
    
  2. そのattachable_sgidを取得し、フロントエンドに対して<action-text-attachment>タグを使用してリッチテキストのコンテンツに挿入するように依頼します:

    <action-text-attachment sgid="BAh7CEkiCG…"></action-text-attachment>
    

これはBasecampに基づいていますので、まだお探しの情報が見つからない場合は、このBasecampドキュメントをご確認ください。

フィードバック

このガイドの品質向上にご協力ください。

タイポや事実の誤りを見つけた場合は、ぜひ貢献してください。 開始するには、ドキュメントへの貢献セクションを読んでください。

不完全なコンテンツや最新でない情報も見つかるかもしれません。 メインのドキュメントに不足しているドキュメントを追加してください。 修正済みかどうかは、まずEdge Guidesを確認してください。 スタイルと規約については、Ruby on Rails Guides Guidelinesを確認してください。

修正すべき点を見つけたが、自分で修正できない場合は、 問題を報告してください

そして最後に、Ruby on Railsのドキュメントに関するあらゆる議論は、公式のRuby on Railsフォーラムで大歓迎です。