1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

RansackでActionTextの中を検索する

Posted at

はじめに

Ransackは、複雑な検索機能でも簡単に作れるGemです。そして、ActionTextはRails6から導入されたリッチテキストを簡単に製作できる機能です。
RansackでActionTextの中を検索できないという記事がありましたが、どうやら検索できるようなので、記事を書こうと思いました。

注意

RansackやActionTextの導入は割愛させていただきます。
大事なところだけです。
また、恥ずかしながら私自身がRailsを勉強中なこともあり、完全に理解しれきていないと思いますので、他の記事でも調べて頂いた方がいいと思います。最大限頑張って説明させていただきます。

結論

Ransackで検索するためには、モデルにアソシエーションを追加する必要がありました。
結論としては、has_oneの行が必要ということです。
2つ同じ指定のように思えますが、片方が読み書き用で、片方が検索用と考えてもらうといいと思います。

app/models/message.rb
class Message < ApplicationRecord
  has_rich_text :content
  has_one :content, class_name: 'ActionText::RichText', as: :record
end
app/views/messages/index.html.erb
 <%= search_form_for @q, url: search_messages_path do |f| %>
    <%= f.label :title_or_content_body_cont, 'テキスト検索' %>
    <%= f.search_field :title_or_content_body_cont %>

説明

結論の例では、messageモデルに、「has_rich_text :content」でActionTextを紐付けています。
ここまではRailsガイドのとおりです。これがないとActionTextのデータが生成できません。

しかし、この「has_rich_text」に関しては、Ransack対応していないようです。
そのため、更にもう1行追加が必要です。

それが「has_one :content, class_name: 'ActionText::RichText', as: :record」です。
私は「class_name」と「as」は見慣れない記述だったので、Railsドキュメントを探したところ次のように記述がありました。

オプション 説明
class_name 関連名と参照元のクラス名を異なるものにしたい場合に指定
as ポリモーフィック関連を定義

class_nameで指定されたほうを見に行っているようです。
つまり、ActionText::RichTextクラスを参照しているようです。

asのポリモーフィック関連とは、テーブルのリレーションが直接接続されていないテーブルにアソシエーションを可能にすることができるようです。ただし、対象のレコードは「polymorphic: true」で生成されている必要があり、ActionText内のbelogns_toでも「polymorphic: true」の指定が必要になります。

確認してみると、ActionTextのマイグレーションファイルを見るとたしかにデフォルトで「polymorphic: true」が入っています。

db/migrate/XXXXXXXXXXXXXXXX_create_action_text_tables.action_text.rb
class CreateActionTextTables < ActiveRecord::Migration[6.0]
  def change
    create_table :action_text_rich_texts do |t|
      t.string     :name, null: false
      t.text       :body, size: :long
      t.references :record, null: false, polymorphic: true, index: false

      t.timestamps

      t.index [ :record_type, :record_id, :name ], name: "index_action_text_rich_texts_uniqueness", unique: true
    end
  end
end

また、RailsのGithubを確認すると、ActionText::RichTextクラスにて、recordのbelogns_toで「polymorphic: true」が指定されていることが確認できます。
(おそらくこのファイル)

rails-main/actiontext/app/models/action_text/rich_text.rb
module ActionText
  class RichText < Record
    self.table_name = "action_text_rich_texts"

    serialize :body, ActionText::Content
    delegate :to_s, :nil?, to: :body

    belongs_to :record, polymorphic: true, touch: true

これらにより、(今回の例では)messageから、直接つながっていないaction_text_tablesにアクセスできるようになり、そのbodyを検索することが可能になりました。

参考

Go Rails / How do I search Action Text with Ransack?
GitHub rails/rails
Railsガイド
Railsドキュメント
Qiita / アソシエーションにおけるclass_nameの定義!
Qiita / Railsのポリモーフィック関連付けを理解する

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?