Search code examples
ruby-on-rails-3sortingsearchransack

Rails 3 using ransack to search and sort and trying to limit options in sort select


I have a page in my rails application that shows a list of listings (paginated using will_paginate). I am trying to find a good gem to implement searching and sorting with the list on this page. The Ransack gem looked like what i needed but i'm running into an issue with it. This is what my code looks like right now with the Ransack gem.

My model (didn't include the whole model, didn't want the validations and extra code to get in the way):

UNRANSACKABLE_ATTRIBUTES = ["id", "state", "show_email", "email", "show_phones", "primary_phone", "secondary_phone", "updated_at", "user_id"]

def self.ransackable_attributes auth_object = nil
  (column_names - UNRANSACKABLE_ATTRIBUTES) + _ransackers.keys
end

My controller action:

def index
  @search = Listing.search(params[:q])
  @listings = @search.result.paginate(page: params[:page], per_page: 20, joins: "LEFT OUTER JOIN attachments ON listings.id = attachments.attachable_id", select: "listings.*, COUNT(attachments.id) AS photos", group: "listings.id", order: "listings.created_at DESC, listings.title ASC, listings.id DESC")
  @search.build_sort if @search.sorts.empty?
end

My search form on the page:

    <div class="advanced-search">
        <%= search_form_for @search do |f| %>
            <div class="search-by">
                <div class="search-field">
                    <%= f.label :title_cont, "Title Contains" %>
                    <%= f.text_field :title_cont %>
                </div>
                <div class="search-field">
                    <%= f.label :description_cont, "Description Contains" %>
                    <%= f.text_field :description_cont %>
                </div>
                <div class="search-field">
                    <%= f.label :price_gteq, "Price Between" %>
                    <%= f.text_field :price_gteq %>
                    <%= f.label :price_lteq, "and" %>
                    <%= f.text_field :price_lteq %>
                </div>
            </div>
            <div class="sort-by">
                <%= f.sort_fields do |s| %>
                    <%= s.sort_select %>
                <% end %>
            </div>
            <div class="search-actions">
                <%= f.submit "Search" %>
            </div>
        <% end %>
    </div>

My route:

resources :listings do
  collection do
    match 'search' => 'listings#index', via: [:get], as: :search
  end
end

With everything i have in place now i have been able to get the application to successfully search and sort the listings.

My question: The sort_select field is showing everything option that is "ransackable". Is there a way to make one attribute available for the searching, but not the sorting? For example i want the ability to search on the description attribute but it doesn't make any sense to include that attribute in the sorting. How can i use an attribute in one and not the other? Thanks for any help and let me know if my question is not clear enough.


Solution

  • Couldn't figure out how to get the values i wanted into the dropdown so i just used links instead. Here's what i ended up with for the sorting.

    Sort by <%= sort_link @search, :title %> | <%= sort_link @search, :price %> | <%= sort_link @search, :created_at, "Date Listed" %>