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
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