Sunspot
Note on Sunspot Solr Binary
There is an optional gem, `sunspot_solr`, which offers a pre-packaged Solr distribution for local development. Some online guides recommend installing this and give examples of using it. This information can be very confusing to new users, and we do not recommend it. There are no command line tools or Rake tasks for starting, stopping or restarting a Websolr index. Additionally, the pre-packaged Solr distribution may be a very different version from your Websolr index, which means it will behave differently in a local environment.
Step 1: Set up a Websolr Index
- If you’ve signed up with us at https://websolr.com, you will want to follow the directions here. When it comes to choosing a Solr configuration, make sure to pick the Sunspot option.
- Heroku users should follow these directions. Websolr will default to creating the new index using Sunspot’s configuration. You can also specify it via the command line, like so:
heroku addons:create websolr[:PLAN] [-a APP_NAME] --config=sunspot
Step 2: The Solr Index URL
When you have successfully created your index, it will be given a semi-random URL. You can find this in the Websolr.com Dashboard, in the Overview tab. From this view, you can also verify that the Configuration in use is Sunspot’s:

WEBSOLR_URL created when Websolr is added to the application. This variable will contain the fully-qualified URL to the cluster.
/select or /admin/ping to your URL and requesting the resource:
Using curl:
curl https://us-east-1.websolr.com/solr/a1b2c3d4e5/select
{"responseHeader":{"status":0,"QTime":59},"response":{"numFound":0,"start":0,"docs":[]}}
Using a browser:

Note on Solr endpoints
/select, /update, /admin/ping, /admin/luke, etc, will result in an HTTP 503 error. This does not mean that the index is offline, just that the user has made an incomplete request. If you absolutely want to verify whether your index is up and running, append /admin/ping to your URL and see what happens.
Step 3: Install the Gem
To install Sunspot, you will need the sunspot_rails gem. Add the following to your Gemfile outside of any blocks:
gem 'sunspot_rails'
Make sure to bundle install. This will install the libraries necessary to use Sunspot.
Step 4: Tell Sunspot where your Solr Index is located
You can optionally also create a sunspot.yml file with this Rake task:
rails generate sunspot_rails:install
The sunspot.yml file looks something like this:
production:
solr:
hostname: localhost
port: 8983
log_level: WARNING
path: /solr/production
development:
solr:
hostname: localhost
port: 8982
log_level: INFO
path: /solr/development
test:
solr:
hostname: localhost
port: 8981
log_level: WARNING
path: /solr/test
sunspot.yml file will supersede your WEBSOLR_URL variable in the environment running the Rails app! This means that Heroku users who have added Websolr to their app should not create the sunspot.yml file unless they have a good reason. And if you do create it, you’ll need to edit it to point to the right location(s).
sunspot.yml file that points to different indices, you can do something like this:
production:
solr:
hostname: us-east-1.websolr.com
port: 443
scheme: https
path: /solr/0a1b2c3d4e5f
development:
solr:
hostname: us-east-1.websolr.com
port: 443
scheme: https
path: /solr/blahblahblah
test:
solr:
hostname: us-east-1.websolr.com
port: 443
scheme: https
path: /solr/s0m3t35tth1ng
It is also possible to add some additional parameters to the sunspot.yml file, which override the default behaviors. You can find documentation on these different parameters here.
Step 5: Add Sunspot to your Models
Any model that you will want to be searchable with Sunspot will need to be configured to do so by adding the searchable block with its attributes. Our demo app has a User model that looks something like this:
class User < ActiveRecord::Base
searchable do
text :first_name
text :last_name
text :email
text :address
text :city
integer :zip_code
text :company
text :company_description
end
end
This makes the model searchable with Sunspot.
Step 6: Create a Search Route
You will need to set up a route to handle searching. The easiest way to do this is to have a search route per model. This involves updating your models’ corresponding controller, and defining a route in config/routes.rb. You’ll also need to have some views that handle rendering the results, and a form that posts data to the controller(s). Take a look at how we implemented this in our demo app for some examples of how this is done.
Our Example
In our example Rails app, we have one model, User, with a handful of attributes. It looks something like this:
class User < ActiveRecord::Base
searchable do
text :first_name
text :last_name
text :email
text :address
text :city
integer :zip_code
text :company
text :company_description
end
end
To implement search, we used the file called app/controllers/users_controller.rb and added this code:
def search
@results = User.search { fulltext "#{params[:q]}"}.results
end
Note on Hits vs. Results
User#search method above returns a Sunspot data structure of the matching object IDs. Calling .hits on this data structure will return the IDs, while calling .results will return the actual ActiveRecord objects. See the Readme file for more information.
We then created a route in the config/routes.rb file:
resources :users do
collection do
post :search # creates a route called users_search
end
end
Next, we need to have some views to render the data we get back from Solr. The search controller action will be rendered by creating a file called app/views/users/search.html.erb and adding:
<div class="container">
<h3>Search Results</h3>
<% if @results.present? %>
<%= render partial: 'search_result' %>
<% else %>
<h4>Nothing here, chief!</h4>
<% end %>
</div>
This way if there are no results to show, we simply put a banner indicating as such. If there are results to display, we will iterate over the collection(assigning each one to a local variable called result), and passing it off to a partial. Create a file for a partial called app/views/users/_search_result.html.erb and add:
<div class="row">
<div class="col">
<%= link_to "#{result.first_name} #{result.last_name} <#{result.email}>", user_path(result) %><br />
<strong><%= result.company %></strong><br />
<em><%= result.company_description %></em><br />
<br />
</div>
</div>
User model is configured for searching in Solr, and has routes for sending a query to Solr. The next step is to render a form so that a user can actually use this feature. This is possible with a basic form_with helper.
<%= form_with(url: search_users_path, method: "post", class: 'form-inline my-2 my-lg-0', local: true) do %>
<%= text_field_tag(:q, nil, class: "form-control mr-sm-2", placeholder: "Search") %>
<%= button_tag("Search", class: "btn btn-outline-info my-2 my-sm-0", name: nil) %>
<% end %>
This code renders a form that looks like this:

Step 7: Push data into Solr
<Model>.reindex. So if you want to reindex a model called User, you would run User.reindex.
User model, you could run: bundle exec rake sunspot:reindex.
Step 8: Put it all together
At this point you should have all of the pieces you need to search your data using Sunspot. In our demo app, we have this simple list of users:

UsersController#search action, via the route set up in config/routes.rb :

UsersController#search action, where it will be passed to Sunspot, which queries Solr. Solr will search the users index, and return any results to a class variable called @results.
UsersController will then ensure the appropriate views are rendered. Each result will be rendered by the partial app/views/users/_search_result.html.erb. It looks something like this:

Congratulations! You have implemented Sunspot in Rails!
Final Thoughts
You can find information on these additional subjects in the Cookbook section below. And if you have any ideas or requests for additional content, please don’t hesitate to let us know!