Commit 6f589e39 by Hoang Phuc Do

Fix search bug

parent acbd7d6e
......@@ -2,6 +2,7 @@ class ProductsController < ApplicationController
before_action :authenticate_user!, only: [:new, :edit, :create, :update, :destroy]
before_action :set_product, only: :show
before_action :user_can_edit_product, only: [:edit, :update, :destroy]
before_action :set_search, only: [:create, :update, :destroy]
# GET /products/new
def new
......@@ -12,6 +13,7 @@ class ProductsController < ApplicationController
def create
@product = Product.new(product_params.merge(user_id: current_user.id))
if @product.save
@search.add_product(@product)
redirect_to root_url, flash: { success: "Product #{@product.title} is sucessfully created" }
else
render 'new'
......@@ -21,6 +23,7 @@ class ProductsController < ApplicationController
# PATCH/PUT /products/1
def update
if @product.update(product_params)
@search.update_product(@product)
redirect_to root_url, flash: { success: "Product #{@product.title} is sucessfully updated" }
else
render 'edit'
......@@ -31,6 +34,7 @@ class ProductsController < ApplicationController
def destroy
if @product.destroy
flash[:success] = "Product #{@product.title} deleted"
@search.delete_product(@product)
else
flash[:alert] = "Product #{@product.title} can't be deleted"
end
......@@ -56,4 +60,8 @@ class ProductsController < ApplicationController
@product = current_user.products.find_by(id: params[:id])
redirect_to root_url, flash: { alert: 'You do not have permission to edit this product' } if @product.blank?
end
def set_search
@search = Search.new
end
end
\ No newline at end of file
......@@ -13,10 +13,10 @@ class SearchController < ApplicationController
private
def set_search_result
@search_result = if params[:q].present?
Search.new(params[:q]).products
else
Product.all
search = Search.new
@search_result = search.products(params[:q])
if @search_result.blank?
@suggested_keywords = search.suggested_keywords(params[:q])
end
end
end
\ No newline at end of file
module SearchHelper
def render_search_result(search_result)
def render_search_result(search_result, suggested_keywords)
if search_result.blank?
render html: 'Sorry! There are no products matched your query'
keys = suggested_keywords.map { |kw| link_to kw, search_result_url(q: kw) }.\
to_sentence(last_word_connector: ' or ')
suggestion_msg = keys.present? ? " You can try different keywords like #{keys}" : ''
render html: "Sorry! There are no products matched your query. #{suggestion_msg}".html_safe
else
render(partial: 'products/product_list',
locals: { products: search_result })
......
class ProductFilter
def initialize(solr)
@solr = solr
end
def filter_search_query(search_query)
search_query = search_query.blank? ? '*' : RSolr.solr_escape(search_query)
@solr.query_product_title(search_query)
end
def filter_suggest_query(suggest_query)
@solr.query_product_suggestion(RSolr.solr_escape(suggest_query))
end
end
\ No newline at end of file
class Search
def initialize(search_query)
def initialize
@solr = SolrSearch.new
@search_query = search_query
@product_filter = ProductFilter.new(@solr)
end
def products
@solr.search_for(@search_query)
filter_products(@solr.docs)
def products(search_query)
matched_products(@product_filter.filter_search_query(search_query))
end
def suggested_keywords(keyword)
@product_filter.filter_suggest_query(keyword).map { |kw| kw['term'] }
end
def update_product(product)
@solr.update_product_index(product)
end
def add_product(product)
@solr.add_product_index(product)
end
def delete_product(product)
@solr.delete_product_index(product)
end
private
def filter_products(products)
def matched_products(products)
product_ids = products.map { |product| product[:id.to_s] }
Product.find(product_ids)
end
......
......@@ -5,19 +5,39 @@ class SolrSearch
def initialize
@rsolr = RSolr.connect url: Settings.rsolr.address
@response = nil
end
def search_for(search_query)
search_query ||= ''
@response = rsolr.get 'select', params: { q: sanitize_query(search_query) }
def query_product_title(search_query)
response = rsolr.get 'select', params: { q: "title:#{search_query}" }
response['response']['docs']
end
def docs
@response['response']['docs']
def query_product_suggestion(search_query)
response = rsolr.get 'suggest', params: { 'suggest.q' => search_query }
response['suggest']['productSuggester'][search_query]['suggestions']
end
def sanitize_query(query)
query.gsub(/[^0-9A-Za-z]/, '')
def update_product_index(product)
add_product_index(product)
delete_product_index(product)
end
def add_product_index(product)
rsolr.add(id: product.id,
title: product.title,
price: product.price)
rsolr.optimize
end
def delete_product_index(product)
rsolr.delete_by_id product.id
rsolr.optimize
end
def delete_all_product_indexes
rsolr.update(data: '<delete><query>*:*</query></delete>',
headers: { 'Content-Type' => 'text/xml',
'charset' => 'utf-8' })
rsolr.commit
end
end
\ No newline at end of file
......@@ -2,7 +2,7 @@
<a href="#" class="search-toggle"><i class="fa fa-search"></i></a>
<%= form_tag search_result_path, method: :get do %>
<div class="header-search-wrapper">
<%= text_field_tag :q, params[:q], class: 'form-control', placeholder: 'Search...' %>
<%= text_field_tag :q, params[:q], class: 'form-control', placeholder: 'Enter product title...' %>
<%= button_tag raw('<i class="fa fa-search"></i>'), class: 'btn btn-default' %>
</div>
<% end %>
......
......@@ -4,7 +4,7 @@
<h2 class="h2 heading-primary mt-lg clearfix">
<span>Search result</span>
</h2>
<%= render_search_result(@products) %>
<%= render_search_result(@products, @suggested_keywords) %>
<div class="toolbar-bottom">
<div class="toolbar">
......
namespace :import_solr_data do
desc "Import product data from database"
namespace :vs_solr do
desc 'Import product data from database'
task product: :environment do
documents = []
Product.all.each do |product|
documents << { id: product.id, title: product.title, price: product.price }
end
solr_search = SolrSearch.new
solr_search.rsolr.add documents
SolrSearch.new.rsolr.add documents
end
desc 'Remove all index from Solr'
task remove: :environment do
SolrSearch.new.delete_all_product_indexes
end
end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment