【Rails】ActionTextの文字数を省略する方法【truncate】

本記事はこんな方に向けて書いています。

  • Actiontextにtruncateを適用したい方
  • 表示する文字数に制限をかけたい方
  • Actiontextで入力した文字がどこに保存されるか分からない方

Railsには『ActionText』というテキストエディタが用意されています。

このエディタを使えば箇条書き画像の添付など通常のエディタの機能を強化させることができる非常に便利なものです。

ActionTextの参考例

今回はActionTextで入力したものに文字数制限を加える方法を紹介したいと思います。

表示する文字数は『truncate』メソッドを使う

例えば下の画像のように、長い文章全てを表示させたくない場合があります。
その場合、『truncate』というメソッドを使えば表示する文字数を変えることができます。

truncateを適用した例

truncateの使い方は非常にシンプルで、下記のように文字数を制限したい要素の後に『.truncate(表示する文字数)』を書くだけです。

今回contentという要素にのみActionTextを使用しています。

= board.name.truncate(25)

*省略記号の『…』を入れて25文字であることにご注意ください。

ActionTextで入力したcontent要素にも同じく下記のように『truncate(100)』と制限を加えてみましょう。

犬

なぜかcontentの方はtruncate使えないんだけど!!

このようにActionTextを使用した場合、一般的な書き方ではエラーが出てしまいます。

これはActionTextで入力したデータがどのような形で保存されているか見ると原因が分かるかと思います。

ActionTextを用いた場合の保存状態を知ろう

ActionTextで入力された文字はどのように保存されているのでしょうか?

ActionTextで入力した値は、Boardテーブルに保存されずに『action_text_rich_texts』テーブルに別で保存されます。

actiontextをインストールして、マイグレーションすると下記のようなテーブルが作成されるようになっています。

  create_table "action_text_rich_texts", force: :cascade do |t|
    t.string "name", null: false
    t.text "body"
    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

それではコンソールを使って整理していきましょう。
まずは最初のboardを取り出してみます。
*ActionTextで入力したcontentは表示されていないことに注意!!

irb(main):003:0> board = Board.first

=> #<Board id: 1, name: "test1", created_at: 
"2020-11-16 07:45:39", updated_at: "2020-11-16 07:45:39", 
user_id: 1, tag_list: nil>

boardのnameに入力された文字を取り出します。

irb(main):004:0> board.name
=> "test1"

一般的な表示のされ方ですね。
では、今度はboardのcontentを取り出します。

irb(main):005:0> board.content

=> #<ActionText::RichText id: 1, name: "content", 
body: #<ActionText::Content "<div class=\"trix-conte...">, 
record_type: "Board", record_id: 1, created_at: 
"2020-11-16 07:45:39", updated_at: "202
犬

!!!なんだこの表示は!!

ActionTextを適用した要素は、上記の実行結果の中にある『body:』の中に格納されます。

そして格納された文字は『div class = …..』のように単なる文字ではなく、HTMLの要素として保存されているのです。

ですので、先程のようにtruncate(100)と書くとエラーが発生します。

= body.content.truncate(100)

どうやらHTMLの要素を除いてやれば良さそうですね!!

HTMLの除去は『strip_tags』を使おう

まずはActionTextを適用した文字にtruncateを効かせる書き方をみておきましょう。

= truncate(strip_tags(board.content.to_s),length: 100)

board.contentには無駄なHTML要素が含まれるので、それらを除去するために『strip_tags』メソッドを使用します。

あとはtruncate()で括ってやればOKです。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です