Pass current_scopes on to search

2019-06-04 11:31发布

问题:

I'm using the very helpful has_scope gem. I have an index page created by passing scopes in a link.

<%= user_collections_path(@user, got: true) %>

On that index page I can query the current_scopes.

I have a pretty standard ransack search form on that page but using it returns results without any scopes.

How can I pass the current_scopes on to the search? I tried using a hidden field but couldn't get it to work. I thought if I could pass the scopes in a link I ought to be able to pass them in a form but after googling I'm not sure that is true.

Search form

<%= search_form_for @search, :html => {:method => :post} do |f| %>
    <%= f.text_field :name_or_miniature_name_cont, class: "span3" %>
    <%= f.submit "Search", class: "btn" %>
<% end %>

Index method

 def index
    @user = User.find_by_username(params[:user_id])
    @search = apply_scopes(@user.collections).search(params[:q])
    @search.sorts = 'created_at desc' if @search.sorts.empty?  
    @collections = @search.result.paginate(page: params[:page])
 end

回答1:

Using the new functionality in Ransack 1.6+ you can introduce scopes into your Ransack search, but first you need to whitelist them, like so:

class Employee < ActiveRecord::Base
  scope :active, ->(boolean = true) { where(active: boolean) }
  scope :salary_gt, ->(amount) { where('salary > ?', amount) }

      # `ransackable_scopes` by default returns an empty array
      # i.e. no class methods/scopes are authorized.
      # For overriding with a whitelist array of *symbols*.
      #
   def self.ransackable_scopes(auth_object = nil)
    [:active, :salary_gt]
   end
end

Then you can trigger them like this:

Employee.ransack({ active: true, hired_since: '2013-01-01' })

Employee.ransack({ salary_gt: 100_000 }, { auth_object: current_user })

You can also add them to your search_form_for as per normal.

I hope this helps.



回答2:

You could store / retrieve the data from the current session rather than to put it into a url parameter.

To quote a comment on an issue:

This is the reason has_scope supports :default, so you can give a proc a retrieve the value from session:

has_scope :degree, :default => proc { |c| c.session[:some_value] }



回答3:

You could pass current scopes in the action url:

<%= search_form_for @search, url: search_people_path(current_scopes), do |f| %>