I have an earlier post describing the way I set up a ransack search that sets up check boxes for possible search values in a given field. This was my first time using ransack and to say I had no idea what I was doing was not too far off. I’ve recently had to use it for another app and took some time looking into it again. And I think I’ve found the correct way to do a search like this.

What I have is a table with a field called electroding_material. When filling out a form for a new object, this field is filled using a dropdown table with three choices; NiCr, Inconel, Other. In my search form, I want to have checkboxes that will let me search for say only those that are NiCr or Inconel. Here’s how I did it.

My Model:

MATERIALS = ['NiCr', 'Inconel','Other']

My View:

<%= search_form_for @q, :url => results_path, :html => {:method => :post} do |f| %>
  <%= f.label :electroding_method, 'Electroding Method ' %>
<% Electroding::METHODS.each do |method| %> <%= check_box_tag 'q[electroding_method_eq_any][]', method %> <%= method %>
<%= f.submit 'Search' %> <% end %>

Important to note that I used check_box_tag and not f.check_box. Check_box is for things that are directly tied to the model. When things are not directly tied to my model (as is the case here), use check_box_tag. Another important note is the extra [] after the q[electroding_method_eq_any]. This makes sure that it sends an array of values in the search option.

My Controller:

def results
    @q = Plate.search(params[:q])
    @plates = @q.result.by_serial_number
    
    if @plates.empty?
      redirect_to compare_path, notice: "No matching plates"
    else
      render action: "results"
    end
  end

The by_serial_number scope just orders everything by its serial number.