Skip to content

How to yes/no/any on a scope taking a boolean argument? #1661

Description

@kalsan

I'm trying to figure out the most elegant way to achieve the following with ransack: Imagine a Rails model User that has_many :licenses of type License. Now, I'd like to add a filter "Has at least one license" to a filter form for users where I can choose between:

  • doesn't matter ("any"), filter is not active
  • "Yes"
  • "No"

Seemed obvious at first, but I've just spend hours doing this in many wrong ways.

Here's what I've tried:

First attempt: Two scopes

I've implemented scopes with_licenses and without_licenses. I was unable to combine those into a single select input in the filter form.

Second attempt: Custom ransacker

I've implemented a custom ransacker ransacker :licenses_exist and called the select field :licenses_exist_true or :licenses_exist. In both cases, the form attempts to call .licenses_exist_true or .licenses_exist on ransacker's Search object in the value method (which of cause fails). I am getting the feeling that combinding a custom ransacker with a select field does not work with current versions of ransack, very much contrary to the documentation, which states that it should work: https://activerecord-hackery.github.io/ransack/going-further/ransackers/#testing-for-existence

Did I find a bug / am I misunderstanding something?

Third to sixth attempts: scope with a single argument

Something of the sorts scope licenses_exist, lambda {|value| ... }

Attempt 3 was to pass f.select(:licenses_exist, [['', nil], [_('Yes'), '1'], [_('No'), '0']]), where values like 1, "1", true, "true", and even "yes" were eaten by ransack and no argument was passed to the lambda.

Attempt 4 was to make the lambda's argument optional, but then I could not distinguish between the case "any" and "no".

Attempt 5 was to set config.sanitize_custom_scope_booleans = false in an initializer, which broke all of my other scopes, of course.

And the final attempt, number 6, is that I have f.select(:licenses_exist, [['', nil], [_('Yes'), 'y'], [_('No'), 'n']]) since those are not eaten by Ransack.

Struggle is real. This can't be that hard, can it? After all, my second attempt is even documented on the documentation. What am I doing wrong? How to do this for real?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions