Closed4
Railsで検索ツールを実装する際の検討・実装の流れ
検索機能にあたっての調査
今回の使用を検討
- タグについてはタグをタップすると検索できるように実装済み
1. Active Modelでclass SearchArticlesFormを作成して実装⭕️
- モデルでクエリ処理をscopeメソッドを作成する
- カリキュラムで実装経験あり。
ActiveModel::Model
とActiveModel::Attributes
をインクルードしたクラスを作成し、検索のためのメソッドを作成 - コントローラでSearchArticlesForm用のインスタンスを作成して検索
- 中間テスト・応用ではこちらを使用。ひとまずgem使わない形で実装する。
gem ransack
を使用して実装
2. - Rails基礎で実装
- Introduction | Ransack documentation
今回は使わないけど参考(全文検索系)
- それほど検索機能を重視していないので今回は選択肢から外す
- ただ RDBMSでSQLの検索行うよりも、自由度高く検索できそうで面白そう。AI使った検索とかできるっぽい。
3. Elasticsearch
- バトランオフ会でかずちゃんさんが使ったと話してた
- 大量データ、スピード検索に良いらしい。
RDBMS => データベース => テーブル => 列/行
Elasticsearch => クラスター => インデックス => シャード => キーバリューペアから構成されたドキュメント
引用元:Elasticsearchのインデックスとは? | Elastic Blog
使用するgem
4. Solr
-
これも近しい言葉で検索できるっぽい
-
Solr検索エンジンを使うためのライブラリでSolrはElasticsearchと似ているらしい(参考)
-
最近の記事があんまりなかった
-
使用するgem
5. Algolia
FormObjectの導入
FormObjectとは何か?
- モデルとフォームの責務を切り分けることができる
- Railsでは基本的にフォームはモデルに依存している(ユーザー新規登録ででform_withを使う際、
model: @user
と指定していることからも分かる) - ただ複数のモデルに依存するフォーム(検索など)やモデルが存在しないフォーム(ログインなど)もあり、その際使えるのがFormObject
- 【Rails】FormObject を使って、複数のテーブル情報を同時保存 #Ruby - Qiita
導入の方法
- app配下にformディレクトリを作成して、そこに必要なフォームを作成
$ mkdir app/forms
$ touch app/forms/search_posts_form.rb
- ファイル名はスネークケース、クラス名はキャメルケース(Railsだとこの辺りrails gすると自動で生成されるのであまり意識したことがなかった)
-
ActiveModel::Model
とActiveModel::Attributes
をインクルードする
class SearchPostsForm
include ActiveModel::Model
include ActiveModel::Attributes
end
参考資料
検索用のフォームビューを作成
ルーティングの設定
config/routes.rb
resources :posts do
collection do
get :search
end
end
-
search_posts_path
が使えるようになる
フォームの作成
app/views/posts/_search_post_form.html.erb
<%= form_with model: search_form, url: search_posts_path, scope: :q, method: :get do |f|%>
<%= f.search_field :address_or_body,
id: 'search_field_of_post',
class: 'input input-borderd input-accent form-control mb-6 w-full md:w-1/2 mx-auto',
placeholder: '場所・投稿内容' %>
<%= f.submit '検索', class: 'btn btn-primary w-full my-6' %>
<% end %>
-
method: :get
:form_withのアクションを指定。何もつけないとデフォルトはPostメソッドになるため、ActionController::RoutingError (No route matches [POST] "/posts/search"):
とエラーが出る。 - form_with | Railsドキュメント
enumで選択式の検索を実装する際の注意点
viewファイル
app/views/posts/_search_post_form.html.erb
<%= f.select :genre_select, Post.enum_options_for_select(:genre), { include_blank: "未選択" },
id: 'search_field_of_genre',
class: 'bg-card-body bg-base-100 rounded-3xl border border-accent py-2 px-3 mb-6 w-full md:w-1/2 mx-auto' %>
- 基本的には入力用のフォームの転用でいいが、paramsとattributeに合わせてプロパティの変更が必要(今回は
:genre_select
にしてみた) - Action View フォームヘルパー(セレクトボックス)
フォームオブジェクトの設定
app/forms/search_posts_form.rb
class SearchPostsForm
include ActiveModel::Model
include ActiveModel::Attributes
# フォームと関連付けするための属性。ActiveModel::Attributesがあるから設定できる。
attribute :address_or_body, :string
attribute :genre_select, :string
#...
end
-
attribute
を:string
にしておく必要がある - 最初enum使っているのでintegerにしたら何で検索してもenumで0にしてある和食しか出てこなかった
このスクラップは3ヶ月前にクローズされました