概要
ActiveAdminの検索条件を追加するにあたり、ちょっと複雑な条件で検索をかけたかったです。いろいろ検討した結果、生のSQLを組む実装となったので、その方法を残しておきます。
activeadminの実装
app/admin/users.rb
ActiveAdmin.register Article do
filter :search_name, as: :string
end
Modelの実装
app/models/User.rb
SQLはもっと複雑な感じで同じテーブルの外部キーがあったり、joinした先のさらに先のテーブルの項目見たり…
# 検索条件:キーワード
scope :search_keyword, lambda { |keyword|
sql = "SELECT * FROM users LEFT JOIN users u1 ON users.partner1_id = u1.id LEFT JOIN users u2 ON users.partner2_id = u2.id"
User.find_by_sql(sql)
end
def self.ransackable_scopes(_auth_object = nil)
%i(search_keyword)
end
このまま実行するとエラーがおきます。
undefined method where' for #<Array:0x0000ffff79a1ee50> Did you mean? when
find_by_sqlの戻り値がArrayなので、ActiveRecord_Relation型に変換する必要があったようです。
User.search_keyword("abc").class
=>Array
# 期待するのはこっち
=> User::ActiveRecord_Relation
コードを以下のように書き換えると…できた!!
as_array = User.find_by_sql(sql)
as_relation = where(id: as_array.map(&:id))
参考