Popular Posts

суббота, 31 марта 2012 г.

Поиск в Rails (search in rails), используем sunspot

Привет

Давайте добавим поиск, у нас уже есть Post, Comment по которым можно что-то искать.
Для поиска я буду использовать Solr, который форкнут для rails Sunsop Solr.
и так начнм с установки в наш Gemfile:
gem 'sunspot_rails' #форк для rails
gem 'sunspot_solr'  #сам Solr
gem 'progress_bar'  #нужен для индексирования
group :test, :development do #в группу для разработки и тестирования
  gem "sunspot-rails-tester" #это нужно для запуска тестов, иначе не работает.
  #...
end
Ну и делаем bundle install, для установки gem'ов.
Хорошо теперь в модели нашей в Post, по которой и будет поиск добавляем след. блок:
class Post < ActiveRecord::Base
  after_create :reindex!
  after_update :reindex!

  searchable do
    text :title, :content
    integer :user_id
    time    :created_at
  
    string :sort_title do
     title.downcase.gsub(/^(an?|the)/, '')
    end
  end
  #...
  
  protected

    def reindex!
      Sunspot.index!(self)
    end
end
Блок searchable нужен для описания наших полей, тут можно добавить больше или наоборот убрать больше читайте в вики.
Тип text указывает, что это текстовые поля, time -- время. Здесь понятно, этот блок нужен для полнотекстового поиска по модели.
Также я добавил два callback'а, это нужно для того, чтобы когда мы добавим новый пост, был произведён переиндексирования, тоже
самое и для обновления поста. Какие здесь подводные камни? Нет переиндексации для комментариев, да?
Так теперь сделаем отдельный контроллер для поиска, хотя можно использовать и PostsController, но я лучше вынесу в отдельный
контроллер.
rails g controller search
#controllers/searc_controller.rb
class SearchController < ApplicationController

  def search
    @post = Post.search {
      keywords params[:query]
      order_by :created_at, :asc
    }.results
    render 'posts/index'
  end
end
Поиск делается методом search, который принимает блок, что в блоке, смотрите в вики, мне хватило, чтобы было
отсортировано по дате, а слова поиска указываются в параметрах. Ну и так как своего представления нет для
этого контроллера, то показываем на index из контроллера Posts.
Теперь сделаем форму поиска:
#posts/_search.html.erb
<%= form_tag search_path, :method => :get do %>
  <p>
    <%= text_field_tag :query, params[:query] %>
    <br />
    <%= submit_tag "Search!" %>
  </p>
<% end %>
Вот простая форма для поиска.


Теперь добавим для тестов несколько строк:
#spec/spec_helper.rb
$original_sunspot_session = Sunspot.session

RSpec.configure do |config|
 
  config.before do
    Sunspot.session = Sunspot::Rails::StubSessionProxy.new($original_sunspot_session)
  end
    config.before :each, :solr => true do
    Sunspot::Rails::Tester.start_original_sunspot_session
    Sunspot.session = $original_sunspot_session
    Sunspot.remove_all!
  end
  #......
  #......
  #......
end
Вот теперь всё прекрасно.
Как запускать?
rake sunspot:solr:start
#=>java version "1.6.0_23"
   OpenJDK Runtime Environment (IcedTea6 1.11pre) (6b23~pre11-0ubuntu1.11.10.2)
   OpenJDK Server VM (build 20.0-b11, mixed mode)
   Removing stale PID file at /home/mike/app/example-app/solr/pids/development/sunspot-solr-development.pid
   Successfully started Solr ...

Как остановаить?
rake sunspot:solr:stop
#=>java version "1.6.0_23"
   OpenJDK Runtime Environment (IcedTea6 1.11pre) (6b23~pre11-0ubuntu1.11.10.2)
   OpenJDK Server VM (build 20.0-b11, mixed mode)
   Successfully stopped Solr ...



сам gem на гитхабе
тоже
вики
railscasts

Комментариев нет:

Отправить комментарий