about 4 years ago

Ransack
Rails內做search form的Gem
https://github.com/activerecord-hackery/ransack

這次的實作與官方教學有一些不同,以下貼code記錄

首先安裝gem

Gemfile
gem "ransack", github: "activerecord-hackery/ransack", branch: "rails-4"

由於我想要達到example.com/search?#{params}的效果所以我的做法是先產生search controller和index頁面,並在route內設定

routes.rb
get "/search" => "search#index", :as => "search"

接下來就是ransack出場的時候了
我們可以在search controller中下search(params[:q])或是ransack(params[:q])來做搜尋
這邊必須要註記一下,q只是一個ransack幫預設的param key,我們可以參考ransack的文件來決定我們要搜尋的是這個model下的哪些資料,也可以搜尋associate的資料,參考的wiki如下:
https://github.com/activerecord-hackery/ransack/wiki/Basic-Searching

在此例我要搜尋的是Topic model內的title和content
所以在controller中的操作就是
1.處理params[:q]拿到的資料,把特殊字元拿掉

def validate_search_key
  @query_string = params[:q].gsub(/\\|\'|\/|\?/, "") if params[:q].present? #這一段

  @search_criteria = search_criteria(@query_string)
end

2.告訴controller我們要找的資料範圍

def search_criteria(query_string)
  { :title_or_content_cont => query_string } #title_or_content_cont 是ransack提供的方法

end

3.完成index action

def index
  if @query_string.present?
    @search = Topic.search(@search_criteria).result(:distinct => true)  
  end
end

這樣就大致完成了,剩下來的就是view的部分,也要記得判斷有沒有@query_string,否則若搜尋不到就會噴錯
搜尋結果會長這樣:
http://example.com/search?utf8=✓&q=test
q=test就是我們的搜尋內容
utf8=✓則是為了符合ie6,rails自動在form中幫我們加上的attribute
會出現的原因是因為我們用get方法做搜尋
如果是用post應該就會有不同的樣貌
之後再試試看:)

controller全貌如下:

search_controller.rb
class SearchController < ApplicationController
  before_action :validate_search_key

  def index
    if @query_string.present?
      @search = Topic.search(@search_criteria).result(:distinct => true)  
    end
  end
  
  protected
  
  def validate_search_key
    @query_string = params[:q].gsub(/\\|\'|\/|\?/, "") if params[:q].present?
    @search_criteria = search_criteria(@query_string)
  end

  def search_criteria(query_string)
    { :title_or_content_cont => query_string }
  end

end
← 網頁開發Road Map Ruby Class and Module →
 
comments powered by Disqus