LoginSignup
30
17

More than 5 years have passed since last update.

Ransackで自前scope使う時に'1'や'0'を値として渡せない?

Last updated at Posted at 2015-06-23

Ransackで自前scope使う時に'1'や'0'を値として渡せない?

Railsアプリに簡単に検索機能を追加できるransackを使っています。
ここで一つの問題にぶつかってしまいました。

ぶつかった問題

検索値に1を設定するとArgumentError (wrong number of arguments (0 for 1))が発生する。
(0、2、3、、、、なら発生せず)

やりたいこと

Viewからselectで選択したメニューの値(1,2,3,..)を受け取り、その値を検索値とし、自前のscopeをransack経由で使おうとしました。

以下はモデルとコントローラー抜粋。

app/models/report.rb
:
scope :pathogen_eq, ->(pathogen) {joins(:test_results).merge(TestResult.where(pathogen: pathogen)).uniq}
:
def self.ransackable_scopes(auth_object = nil)
    %i(pathogen_eq)
end
:
app/controller/reports_controller.rb

def index
  @q = Report.ransack(params[:q])
:
end

何が起こっている?

エラーをキーワードに検索すると、RansackのIssueに次のようなものが見つかりました。

Wrong result and errors for join/group/having scope with certain values (0 and 1) #502
Issue502

  • scopeに渡すときに、0と'0'をfalseに、1と'1'をtrueに変換しているので、値で渡せない
  • 0と1は変換しないように修正(一旦Close)
  • 今度はチェックボックスの場合に問題発生(ReOpen)
  • その後修正のやり取りがあるけどテストが通らずOpenのまま

という状況のようです。

ransackのソースを見ると、確かに0と1はboolean扱いになっていました。

ransack/lib/ransack/constants.rb
module Ransack
  module Constants
:
    TRUE_VALUES = [true, 1, '1', 't', 'T', 'true', 'TRUE'].to_set
    FALSE_VALUES = [false, 0, '0', 'f', 'F', 'false', 'FALSE'].to_set
    BOOLEAN_VALUES = (TRUE_VALUES + FALSE_VALUES).freeze
:

対応

全てをRansackに任せる必要はなかったので、値渡しのところは自前でscopeを呼ぶようにしました。

app/models/report.rb
:
scope :pathogen_eq, ->(pathogen) {joins(:test_results).merge(TestResult.where(pathogen: pathogen)).uniq}
:
app/controller/reports_controller.rb

def index
  @q = Report.ransack(params[:q])
  reports = @q.result

  if params[:q].present? && params[:q][:pathogen_eq].present?
    reports = reports.pathogen_eq(params[:q][:pathogen_eq])
  end
:
end

値によってはテストも通ってしまうので、使う人は気を付けた方が良いです。
(修正PullRequestまでは手が出せていません、、、)

30
17
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
30
17