1
votes

I use the current version of Ransack gem with Rails 5 and MySQL and want to implement a search form where I can have two select fields:

1) first dropdown select list should contain the table column attributes eg. first_name, last_name, street

2) second dropdown select list should contain the operator like "equals", "is not", "contains"

and then an input field for the search keyword and a submit button.

In code it should look something like this:

<%= search_form_for @search do |f| %>
  <%= f.select :select_criteria, options_for_select([
        ['first name', :first_name], 
        ['last name', :last_name], 
        ['street', :street]
        ]), @search.select_criteria %>
  <%= f.select :operator, options_for_select([
      ['contains', :contains], 
      ['is not', :is_not], 
      ['equals', :equals]
      ]), @search.operator %>
  <%= f.search_field :term %>
  <%= f.submit "filter" %>
<% end %>

But I can't find any examples in the ransack documentation that covers this case.

How does it look correctly?

1

1 Answers

4
votes

Try something like this. I've used this in an application. This uses the technique shown in the ransack demo app.

<%= search_form_for @search do |f| %>
  <%= f.grouping_fields(f.object.new_grouping) do |g| %>
    <%= g.condition_fields(g.object.new_condition) do |c| %>
      <%= c.attribute_fields do |a| %>
        <%= a.attribute_select only: %i(id) %>
      <% end %>
      <%= c.predicate_select only: %i(cont not_eq eq) %>
      <%= c.value_fields do |v| %>
        <%= v.text_field :value %>
      <% end %>
    <% end %>
  <% end %>
  <%= f.submit "filter" %>
<% end %>

Ransack can take a group of conditions and search by them all at once. In your case, you can supply one group with one condition. I know this seems fairly verbose, but I'm not sure of a simpler approach with ransack (there could be one though).

I'd say the key lines here are f.grouping_fields(f.object.new_grouping) and g.condition_fields(g.object.new_condition). These work like fields_for in that you need to have at least one grouping setup for the block to render anything.

You can read the full documentation about predicates here. These values can be provided to the only option in c.predicate_select. You can also build custom predicates fairly easily if you need them.

A good source of documentation for ransack is the ransack demo app. For example, here's how they build an advanced search form. You can also look at the live demo of advanced search.

Here's a screenshot of the advanced search demo. It looks relatively similar to what you're trying to achieve.

Example of ransack advanced search