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!
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
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