franckandbeans
franckandbeans

Reputation: 47

Using searchkick with pundit: policyscope error

I am trying to implement a basic search engine with filtering options and i am stuck on the implementation of searchkick. Here is my code:

class ProductsController < ApplicationController
  def index
    if params[:query].present?
      @products = policy_scope(Product.search(params[:query]))
    else
      @products = policy_scope(Product)
    end
  end
class Product < ApplicationRecord
  searchkick
<h1>Products Index</h1>

<%= form_tag products_path, method: :get do %>
  <%= text_field_tag :query,
    params[:query],
    class: "form-control",
    placeholder: "Chercher par produit ou marque"
  %>
  <%= submit_tag "Rechercher", class: "btn btn-primary" %>
<% end %>
<br>

<ul>
  <% @products.each do |product| %>
     <li><%= link_to product.name, product_path(product) %></li>
     <%= cl_image_tag product.photos.first.key, height: 550, width: 550, crop: :fill, quality: 100 %>
  <% end %>
</ul>

I do not know where to make the policy_scope because each time i try to index the search results it returns this error message:

undefined method `all' for #<Searchkick::Results:0x00007f9f117b6530> Did you mean? all?

Thanks in advance for the help!

Upvotes: 1

Views: 279

Answers (2)

systho
systho

Reputation: 1161

Try this

class ProductsController < ApplicationController
  def index
    allowed_products = policy_scope(Product)
    if params[:query].present?
      @products = allowed_products.search(params[:query])
    else
      @products = allowed_products
    end
  end

Policy scope expect a "vanilla" relation, but .search return something a bit too sophisticated, the solution is to first restrict the scope and call .search at the end

UPDATE SearchKick V5 or later

Searchkick no longer allows calling search on a relation. The above solution will not work if you are using the latest version of Searchkick.

You must use the query interface of Searchkick to scope results.

class ProductsController < ApplicationController
  def index
    allowed_product_ids = policy_scope(Product).pluck(&:id)
    if params[:query].present?
      @products = allowed_products.search(params[:query], where: {id: allowed_product_ids})
    else
      @products = allowed_products
    end
  end

Searchkick changelog Raise error when search called on relations

Upvotes: 0

franckandbeans
franckandbeans

Reputation: 47

The result of the search had to be directly implemented in the view and not the controller ! Thanks anyways :)

Upvotes: 0

Related Questions