Neil
Neil

Reputation: 5178

Ransack: return nothing when form submitted and no search values entered

I have the search form and the results of the search posted on the same page.

As I understand it: the default for ransack is that if a form is submitted with no values inputted into the search fields, then all records of that particular resource are returned.

How can I change it so that if a user does a search where they enter no values into the search fields, then none of the records are returned?

Ransack Documentation

This doesn't work:

if params["q"].values.present? # Always returns true because an array of empty strings returns true from method call: present?
  # do this
else
  # do that
end

Neither does this:

if params["q"].values.empty? # Always returns true because an array of empty strings returns true from method call: empty?
  # do this
else
  # do that
end

Checking for params["q"].present? does not work either because every time a form is submitted, whether there are values entered or not, this is what gets passed through to the server:

# showing with pry
[1] pry> params[:q] 
  => {"namesearch_start"=>"",
      "city_cont"=>"",
     }
[2] pry> params[:q].present?
  => true # always returns true

So params["q"] will always be present, whether there are values entered or not.

Upvotes: 3

Views: 1572

Answers (2)

Winston Ferguson
Winston Ferguson

Reputation: 41

I know this is old but here's an alternative:

The ransack method returns a new instance of a Search class, https://github.com/activerecord-hackery/ransack/blob/main/lib/ransack/adapters/active_record/base.rb

Looking at the Search class, https://github.com/activerecord-hackery/ransack/blob/main/lib/ransack/search.rb, we see the inspect method is being overriden to create a better representation of the object. That representation includes a conditional based on any scoped arguments.

So, if you're using @q as the resource, as outlined in the docs like this:

    @q = MyModel.ransack(params[:q])

You can check if it has scopes or conditions with include:

    @q.inspect.include?('scope') || @q.inspect.include?('conditions')

or regex

    @q.inspect.match?(/scope|conditions/)

No search and empty searches will both evaluate to false as neither have scope or condition arguments.

Plus, as we're using the instance variable, we can use this check in both controllers and views.

Upvotes: 0

Mohamad
Mohamad

Reputation: 35349

What you can do is reject any values that are blank.

if params[:q].reject { |_, v| v.blank? }.any? # .none? for inverted
  # Handle search
else
  # Handle no query scenario
end

Or

if params[:q].values.reject(&:blank?).any? # .none? for inverted
  # Handle search
else
  # Handle no query scenario
end

Upvotes: 2

Related Questions