woshidan's loose leaf

ぼんやり勉強しています

Ransackで関連モデルの検索を行う

Ransackでは特定のモデルのカラムだけでなく、そのモデルと関連する他のモデルのカラムでも検索を行うことができる。

例えば、Userモデルに1対多で紐づくCommentモデルのcontents属性で検索したい場合

<%= search_form_for(@q, url: user_search_path) do |f|
    <%= f.search_field comments_contents_cont %>

逆に、Commentモデルに多対1で紐づくUserモデルのname属性で検索したい場合

<%= search_form_for(@q, url: comment_search_path) do |f|
    <%= f.search_field user_name_cont %>

となる。

User<=(1対多)=>UserGroup<=(1対多)=>Group

といった関連のモデルがある場合、

class User < ApplicationRecord
  has_many :user_groups
end
class UserGroup < ApplicationRecord
  belongs_to :user
  belongs_to :group
end
class Group < ApplicationRecord
  has_many :user_groups
end

以下のようにして、Groupの属性からUserを検索することもできる。

<%= search_form_for(@q, url: users_path) do |f| %>
  <%= f.search_field :user_groups_group_name_cont %>

生成されるクエリは以下のような感じ。

  def index
    @q = User.ransack(params[:q])
    binding.pry
    @users = @q.result
  end
[1] pry(#<UsersController>)> @q.result
  User Load (1.8ms)  SELECT "users".* FROM "users" LEFT OUTER JOIN "user_groups" ON "user_groups"."user_id" = "users"."id" LEFT OUTER JOIN "groups" ON "groups"."id" = "user_groups"."group_id" WHERE "groups"."name" LIKE '%グループ%'

参考

qiita.com