Rails 6.0 での新機能 Action Text を試してみた

id:eitoball です。秋ですね。読書の秋といいますが、先日、「われはレギオン」のわれらはレギオン 3: 太陽系最終大戦 (ハヤカワ文庫SF)を読み終えました。物語のテンポがよく、気持ちよく読むことができました。Sci-Fi小説が好きな方には特にお勧めします。(われらはレギオン1 AI探査機集合体 (ハヤカワ文庫SF)われらはレギオン2 アザーズとの遭遇 (ハヤカワ文庫SF) もあわせてお勧めします。)

先日、会社で同僚の何人かと一緒にDHHのAction Textを紹介するYouTube動画を見ました。( Alpha preview: Action Text for Rails 6 )見るだけではつまらないので実際に試したいと思います。

Action Text とは?

Action Text とは、Rails 6.0 で予定されている新機能の1つです。リッチテキストを編集・表示するコンポーネントをページ内に簡単に組み込むことができます。

Basecamp で開発されてきたものを gem として抽出したものです。リッチテキストの扱う部分の主な技術は、trix というJavaScriptライブラリです。これもBasecampで開発されたライブラリです。

Action Text を試してみる

Action Text をDHHの紹介動画と同じように試してみます。Rails 5.2 が使える環境を前提としています。他には、imagemagickとyarnが使えるようになっている必要があります。

アプリケーションの作成

アプリケーションを作成します。そして、作成したアプリケーションのディレクトリに移動します。

$ rails new sample
...
$ cd sample

開発版のrailsに更新

Active Storage で必要な機能が最新版にしかないので開発版のrailsに更新します。また、ついでにwebpackerを追加します。Gemfile を以下のように変更して、bundle install します。

diff --git a/Gemfile b/Gemfile
index 8692b33..5826e6d 100644
--- a/Gemfile
+++ b/Gemfile
@@ -4,7 +4,7 @@ git_source(:github) { |repo| "https://github.com/#{repo}.git" }
 ruby '2.5.1'

 # Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
-gem 'rails', '~> 5.2.1'
+gem 'rails', github: 'rails/rails'
 # Use sqlite3 as the database for Active Record
 gem 'sqlite3'
 # Use Puma as the app server
@@ -35,6 +35,7 @@ gem 'jbuilder', '~> 2.5'

 # Reduces boot times through caching; required in config/boot.rb
 gem 'bootsnap', '>= 1.1.0', require: false
+gem 'webpacker', github: 'rails/webpacker'

 group :development, :test do
   # Call 'byebug' anywhere in the code to stop execution and get a debugger console

そして、webpacker を使えるようにします。

$ bundle exec rails webpacker:install

そして、app/views/layouts/application.html.erb を以下のように変更します。

diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb
index cf19a4b..c0e1732 100644
--- a/app/views/layouts/application.html.erb
+++ b/app/views/layouts/application.html.erb
@@ -5,8 +5,8 @@
     <%= csrf_meta_tags %>
     <%= csp_meta_tag %>

-    <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track': 'reload' %>
-    <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
+    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
+    <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
   </head>

   <body>

Action Text のインストール

Action Text をインストールします。Gemfile を以下のように変更して、bundle install します。

diff --git a/Gemfile b/Gemfile
index 5826e6d..5739b2d 100644
--- a/Gemfile
+++ b/Gemfile
@@ -37,6 +37,9 @@ gem 'jbuilder', '~> 2.5'
 gem 'bootsnap', '>= 1.1.0', require: false
 gem 'webpacker', github: 'rails/webpacker'

+gem 'actiontext', github: 'rails/actiontext', require: 'action_text'
+gem 'image_processing', '~> 1.2'
+
 group :development, :test do
   # Call 'byebug' anywhere in the code to stop execution and get a debugger console
   gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]

そして、Action Text を使えるようにします。

$ bundle exec rails action_text:install
...
$ bundle exec rails db:migrate
== 20181231000000 CreateActiveStorageTables: migrating ========================
-- create_table(:active_storage_blobs)
   -> 0.0047s
-- create_table(:active_storage_attachments)
   -> 0.0043s
== 20181231000000 CreateActiveStorageTables: migrated (0.0092s) ===============

== 20181231000001 CreateActionTextTables: migrating ===========================
-- create_table(:action_text_rich_texts)
   -> 0.0042s
== 20181231000001 CreateActionTextTables: migrated (0.0043s) ==================

ここで3つのテーブルが作成されます。テーブル名からaction_text_rich_textsにリッチテキストが格納されるようです。

Post モデルを作る

リッチテキストを格納するPostというモデルをscaffoldを使って作成します。

$ bundle exec rails generate scaffold Post title:string
...
$ bundle exec rails db:migrate
...

そして、この例のようにリッチテキストを追加できるように以下のように変更していきます。

diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb
index 21c2d4e..d566eaf 100644
--- a/app/controllers/posts_controller.rb
+++ b/app/controllers/posts_controller.rb
@@ -69,6 +69,6 @@ class PostsController < ApplicationController
 
     # Never trust parameters from the scary internet, only allow the white list through.
     def post_params
-      params.require(:post).permit(:title)
+      params.require(:post).permit(:title, :content)
     end
 end
diff --git a/app/models/post.rb b/app/models/post.rb
index b2a8b46..6015acb 100644
--- a/app/models/post.rb
+++ b/app/models/post.rb
@@ -1,2 +1,3 @@
 class Post < ApplicationRecord
+  has_rich_text :content
 end
diff --git a/app/views/posts/_form.html.erb b/app/views/posts/_form.html.erb
index ed01b8b..caeb58d 100644
--- a/app/views/posts/_form.html.erb
+++ b/app/views/posts/_form.html.erb
@@ -16,6 +16,11 @@
     <%= form.text_field :title %>
   </div>
 
+  <div class="field">
+    <%= form.label :content %>
+    <%= form.rich_text_area :content %>
+  </div>
+
   <div class="actions">
     <%= form.submit %>
   </div>
diff --git a/app/views/posts/show.html.erb b/app/views/posts/show.html.erb
index 947ae98..6584299 100644
--- a/app/views/posts/show.html.erb
+++ b/app/views/posts/show.html.erb
@@ -4,6 +4,7 @@
   <strong>Title:</strong>
   <%= @post.title %>
 </p>
+<%= @post.content %>
 
 <%= link_to 'Edit', edit_post_path(@post) %> |
 <%= link_to 'Back', posts_path %>

has_rich_text とか form.rich_text_area が、Action Textによって追加されたメソッドです。

リッチテキストを編集する

Railsサーバーを起動して、実際にリッチテキストを編集してみます。サーバーを起動したら、http://localhost:3000/posts にアクセスして、"New Post" をクリックします。

$ bundle exec rails sever
...
[Webpacker] Compiling…
...

[Webpacker] Compiling… の表示から、webpacker が動作していることが分かります。

<%= form.rich_text_area :content %> と記述した部分にリッチテキスト用のウィジェットが表示されていると思います。ツールバーでテキストを太字にしたり取り消し線を追加することができます。また、画像はドラッグドロップして追加することができます。

f:id:eitoball:20181116131329g:plain
画像をドラッグドロップして追加する

最後に

動画と同じようにさっとリッチテキストに対応ができました。Action TextのGitHubのページには、Action Text is destined for inclusion in Rails 6, which is due to be released some time in 2019. と記載されています。来年のリリースが楽しみです。

採用

Misocaでは、RailsやRubyの新しい機能に興味あるエンジニアも募集しています。

www.wantedly.com