1

I'm trying to understand and set up Sunspot gem in my Rails 4.0 project. I'm trying to implement a better search in my open-source project, BTC-Stores, but I'm a bit confused about how to do that with Sunspot.

Currently, I have the following architecture (model):

Item:

# Relationship with Category
belongs_to :category 
accepts_nested_attributes_for :category

searchable do
    text :name, :description
    integer :category_id
    string  :sort_name do # why I have this here? I dont understand this code
          name.downcase.gsub(/^(an?|the)/, '')
    end
end

Controller:

@search = Item.search do
    fulltext params[:search] do
      boost_fields :name => 2.0
    end

    # With category
    facet :category_id
    with(:category_id, params[:category_id]) if params[:category_id].present?

    # Kaminari
    paginate :page => params[:page], :per_page => 8
end

@items = @search.results

# Here a quick fix to show Category Name, instead of Category ID to user.
@items_categories = []
@search.facet(:category_id).rows.each do |row|
    @items_categories << [Category.find_by_id(row.value), row.count] 
end 
@items_categories = @items_categories.sort_by { |e| e[0].name } 

View:

<% @items_categories.each do |category| %>
    <div class="country-item">
        <a href="#" class="country-row">
            <div class="country">
              <% if params[:category_id].blank? %>
                <%= link_to category[0].name, :category_id => category[0].id  %> (<%= category[1] %>)
              <% else %>
                <%= category[0].name %>(<%= link_to "remove", :category_id => nil %>)
              <% end %>
            </div>
        </a>
    </div>
 <% end %>

The problem:

When I search something, I have the desired results. Take a look at the categories and mainly at the URL:

enter image description here


Now, If i click in any of the listed categories, instead of add the category to "get" params, this is deleting the old params and then adding the category_id param.

Now my URL is http://localhost:3000/stores?category_id=6 instead of http://localhost:3000/stores?utf8=%E2%9C%93&search=bitcoin&category_id=6. Look:

enter image description here

So, what can I doing wrong? And another thing, if you see issues in my code and things that can be better done, please tell me. I read all Sunspot documentation and RailsCast by Ryan Bates, but I don't understand how I can do things by the "right way".

Simone Carletti
  • 173,507
  • 49
  • 363
  • 364
Paladini
  • 4,522
  • 15
  • 53
  • 96

1 Answers1

1

Taking a hint from this answer

Instead of

<%= link_to category[0].name, :category_id => category[0].id  %> (<%= category[1] %>)

Try using

<%= link_to category[0].name, request.parameters.merge({:category_id => category[0].id})  %> (<%= category[1] %>)

This would append the category ID to the existing get parameters.

However this has a downside too - Since you are using Facets, drilling down would keep appending parameters, and you could end up doing an AND by default. i.e. something like

http://localhost:3000/stores?utf8=%E2%9C%93&search=bitcoin&category_id=6&category_id=7

So unless you want the drill down feature by default, you might want to tweak the params merging logic.

Community
  • 1
  • 1
Srikanth Venugopalan
  • 9,011
  • 3
  • 36
  • 76
  • Thanks, this works! But are you sure this is the better way to do this? Why Ryan Bates don't use this and work? (You don't need answer this two question if don't want, but the next one needs :P ). After click in category of my choice, I'm redirected, and in this new page, when I click in "remove" (`<%= link_to "remove", :category_id => nil %>`, my browser go to http://localhost:3000/stores. How can I "merge" my params and remove one of them (category_id, in this cade)? – Paladini Jan 07 '14 at 19:01
  • 1
    Wow, I discovered by myself the answer. Just `<%= link_to "remove", request.parameters.merge({:category_id => nil}) %>`. Again, thanks. – Paladini Jan 07 '14 at 19:02
  • The best answer already is yours, but Can you help me and answer this two questions? "But are you sure this is the better way to do this? Why Ryan Bates don't use this and work?" – Paladini Jan 07 '14 at 19:03
  • 2
    @FernandoPaladini- My only guess is Ryan's [example](http://railscasts.com/episodes/278-search-with-sunspot?view=asciicast) has a single facet scenario :). I haven't come across something better, and yes, it looks odd, but I just add a helper to arrive at the `params` from the get request and use it. – Srikanth Venugopalan Jan 08 '14 at 01:00