Question

I'm having a few problems getting Sunspot implemented! I've tried for the last 2 days to get this working and I can't seem to find any solution (although it no doubt has been staring me in the face!).

I'm wanting the user to be able to search for a vehicles manufacturer. When a vehicle is created, it is assigned a manufacturer through an association (as you can see below). Now.. how do I allow a user to enter in the search field (or even better a collection_select of all manufacturers) and it'll filter out the result?

In an ideal world I'd love this to work as my search:

<%= simple_form_for :search,  url: vehicles_path , :method => :get do |f| %>
    <%= select_tag :manufacturer, options_from_collection_for_select(Manufacturer.all, :id, :name) %> 
    <%= submit_tag "Search", :name => nil %>
<% end %>

But alas, I've not been able to find a solution in my Vehicle model.

If that makes any sense to you, I hope you can lead me in the right direction!

Thanks very much!

class Vehicle < ActiveRecord::Base

    belongs_to :manufacturer

    searchable do
        text    :name, :registration
        integer :manufacturer_id
    end

    def to_s
        self.name
    end
end

Then

class VehiclesController < ApplicationController
  before_action :set_vehicle, only: [:show, :edit, :update, :destroy]

  def index
    @manufacturer = Manufacturer.all

    @search = Vehicle.search do
      fulltext params[:search]
    end

    @vehicles = @search.results
  end
end

and

class Manufacturer < ActiveRecord::Base
    has_many :vehicles

    searchable do
        text    :name
    end

    def to_s
        self.name
    end

end

Vehicle index.html.erb

    <%= form_tag vehicles_path, :method => :get do %>
        <%= text_field_tag :search, params[:search] %>
        <%= submit_tag "Search", :name => nil %>
    <% end %>

And my vehicle form

<%= simple_nested_form_for @vehicle, :html=>{:multipart => true } do |f| %>

  <%= f.error_notification %>

  <div class="form-inputs">
    <%= f.input :name %>
    <%= f.association :manufacturer, include_blank: false %>
</div>

  <div class="form-actions">
    <%= f.button :submit %>
  </div>

 <% end %>

I've removed most of the unnecessary stuff in my examples just for ease.

And just for some laughs, you can look at my failed attempts!

I have also ran so many rake sunspot:reindex it's crazy.

    #integer :manufacturer_id, :multiple => true

    #integer :manufacturer_id, :references => Manufacturer, :multiple => true

    #integer :manufacturer_id, :references => Manufacturer, :multiple => true do
    #   manufacturers.map {|manufacturer| manufacturer.manufacturer_name}
    #end

    #text :manufacturer_names do |manufacturer|
    #  manufacturer.name { |manufacturer| manufacturer.name }
    #end 

    #integer :manufacturer_id {|manufacturer| manufacturer.name }

    #string :manufacturer_name do
    #   manufacturer.name { |manufacturer| manufacturer.name }
    #end

    #text :manufacturers do
    #   manufacturers.map { |manufacturer| manufacturer.name }
    #end

    #integer :manufacturer_id, :stored => true
Was it helpful?

Solution

The problem is in the way you're doing the search in your controller. You said in the ideal world you would like to select the manufacturers from a select element:

<%= simple_form_for :search,  url: vehicles_path , :method => :get do |f| %>
<%= select_tag :manufacturer, options_from_collection_for_select(Manufacturer.all, :id, :name) %> 
<%= submit_tag "Search", :name => nil %>

If you define your search form in this way, you will have a manufacturer parameter in the URL after you submit the form.

You want to filter the vehicles by the id of the manufacturer in your controller, so you can not do a full_text search, you have to use with in the search block:

class VehiclesController < ApplicationController
  def index
    @search = Vehicle.search do
      # Scope the query
      with :manufacturer_id, params[:manufacturer]
    end

    @vehicles = @search.results
  end
end

The sunspot documentation says:

Fields not defined as text (e.g., integer, boolean, time, etc...) can be used to scope (restrict) queries before full-text matching is performed.

You can find more information about scoping: https://github.com/sunspot/sunspot#scoping-scalar-fields

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top