Ransack: Turning off custom scope argument sanitization do not solve scope args problem

Created on 31 May 2018  路  4Comments  路  Source: activerecord-hackery/ransack

We have a scope that we use in active admin as a filter:

class MyModel
  def self.ransackable_scopes(_auth_object = nil)
    %i[ransack_scope_by_user]
  end

  scope :ransack_scope_by_user, ->(user_id) {
    ...
  }
end

When we use it with user with id 1 the user id goes in the params like this:
/path?q[ransack_scope_by_user]=1
we get an error: ArgumentError at /path wrong number of arguments (given 1, expected 0)

Debugging, we find in lib/ransack/context.rb#chain_scope, args = true and so '1' is not passed as argument to the scope. It works fine with any other number of user_id

If we turn off sanitize custom scope booleans as it is said on readme to fix that error
Ransack.configure do |c| c.sanitize_custom_scope_booleans = false end

Then in lib/ransack/context.rb#chain_scope, args = "true" but still '1' is not passed as an argument to the scope.

Most helpful comment

After some search i came to the conclusion that the correct declaration of the method is:

def self.ransackable_scopes_skip_sanitize_args
  [:district_id_eq]
end

If you think about it, it makes much more sense that it is a class method and not specific to an instance. It worked for us after that change.

All 4 comments

Have you ever resolved this issue?

We have the same the problem even if we define our scope in skip sanitize args.

scope :district_id_eq, ->(district_id) {
    joins("join districts on districts.id=#{ district_id } and st_contains(districts.bounds, organization_participations.geometric_coordinates)")
}

def ransackable_scopes_skip_sanitize_args
  [:district_id_eq]
end

as documented in the guides

The only solution we've found is assigning '1' to the param in order to avoid the null value:

  scope :ransack_pending_evaluations_by_user, ->(user_id = 1) {
    pending_evaluations_by_user(User.find(user_id))
  }

After some search i came to the conclusion that the correct declaration of the method is:

def self.ransackable_scopes_skip_sanitize_args
  [:district_id_eq]
end

If you think about it, it makes much more sense that it is a class method and not specific to an instance. It worked for us after that change.

Looks like this one is resolved.

Was this page helpful?
0 / 5 - 0 ratings