Fast Autocomplete Search Terms trong Rails (P1)

Nhiều khi bạn thấy rằng cần có một tìm kiếm toàn cục trong ứng dụng Rails của bạn. ví dụ như tìm kiếm nhiều model trong một form. Có một cách tốt là tìm kiến tự động tại SeatGeek. Bài viết này sẽ thử và đạt được một cái gì đó tương tự như seatgeek

Nhiều khi bạn thấy rằng cần có một tìm kiếm toàn cục trong ứng dụng Rails của bạn. ví dụ như tìm kiếm nhiều model trong một form. Có một cách tốt là tìm kiến tự động tại SeatGeek. Bài viết này sẽ thử và đạt được một cái gì đó tương tự như seatgeek bằng cách xây dựng tìm kiếm tự động hoàn toàn trên nhiều model trong ứng dụng rails của chúng ta. Để làm việc này chúng ta sẽ sử dụng Soulmate Gem .

  1. INSTALLING REDIS

Chúng ta cần cài đặt redis:

  • Nếu là mac bạn chỉ cần chạy lệnh: brew install redis
  • Nếu là hệ thông cơ bản Unix/Linux, cho debian based systems ví dụ: ubuntu chỉ cần chạy: sudo apt-get install redis và trên redhat based systems ví dụ: Fedora/Opensuse chạy sudo yum install redis

Sau đó bạn có thể xác minh nếu redis đã được cài đặt thành công bằng cách bắt đầu máy chủ redis. Mở terminal bạn chạy:

$ redis-server

Bạn có kết qủa tương tự như:

  1. GETTING STARTED

Bây giờ chúng ta có thể bật redis lên và sẵn sàng, hãy bắt đầu tạo một ứng dụng rails 4 để thử soulmate

$ rails new fast-autocomplete

Tiếp theo chúng ta cần thêm gem soulmate và gemfile của bạn. chúng ta cần thêm cả gem faker để điền vào database các bản ghi test thay vì tạo chúng. và chạy bundle install để cài đặt gem.

gem 'faker', github:'stympy/faker'
gem 'rack-contrib'
gem 'soulmate',:require=>'soulmate/server'
  1. CREATING MODELS AND ADDING TEST DATA

Sau khi đã cài đặt được các gem xong, chúng ta sẽ nhanh chóng tạo 2 model scaffold. Chúng ta sẽ có model Noun và model Verb để test dữ liệu. Chúng ta sẽ dễ dàng điền dữ liệu vào bảng sử dụng gem Faker. Sử dụng terminal để chạy lệnh sau:

$ rails g scaffold noun name:string

$ rails g scaffold verb name:string

Tiếp theo cần chạy rake db:migrate để tạo các table trong database của bạn. Chúng ta có thể thực hiện các thao tác CRUD cho cả nouns và verbs tại http://0.0.0.0:3000/nounshttp://0.0.0.0:3000/verbs. Chúng ta có thể tự động thêm dữ liệu trong table của mình bằng cách sử dụng gem Faker và viết code trong file seeds.rb

# create 500 nouns
puts "Creating 'nouns'"500.times doNoun.create(name:Faker::Name.name)end# create 500 verbs
puts "Creating 'verbs'"500.times doVerb.create(name:Faker::Name.name)end

Nó sẽ tạo 500 dữ liệu test nouns và 500 dữ liệu test cho verbs trong database. Chúng ta sẽ đưa dữ liệu vào database bằng cách chạy lệnh sau:

$ rake db:seed

  1. ADDING THE AFTER_SAVE AND BEFORE_DESTROY CALLBACKS

Chúng ta sẽ thêm callback after_savebefore_destroy vào các model (Noun và Verb). after_save sẽ thêm dữ liệu vào Redis thông qua module Soulmate::Loader được cung cấp bởi gem soulmate và before_destroy sẽ xoá dữ liệu từ redis khi một bản ghi được xoá tức là chúng tôi không muốn có một record đơn độc hoặc không sử dụng đến trong database Redis và cũng để tiết kiệm bộ nhớ

noun.rb

classNoun<ActiveRecord::Base
	after_save :load_into_soulmate
	before_destroy :remove_from_soulmate

    validates_uniqueness_of :nameprivatedefload_into_soulmate
		loader =Soulmate::Loader.new("nouns")
		loader.add("term"=> name,"id"=>self.id,"data"=>{"link"=>Rails.application.routes.url_helpers.noun_path(self)})enddefremove_from_soulmate
		loader =Soulmate::Loader.new("nouns")
	    loader.remove("id"=>self.id)endend

verb.rb

classVerb<ActiveRecord::Base
	after_save :load_into_soulmate
	before_destroy :remove_from_soulmate

    validates_uniqueness_of :nameprivatedefload_into_soulmate
		loader =Soulmate::Loader.new("verbs")
		loader.add("term"=> name,"id"=>self.id,"data"=>{"link"=>Rails.application.routes.url_helpers.verb_path(self)})enddefremove_from_soulmate
		loader =Soulmate::Loader.new("verbs")
	    loader.remove("id"=>self.id)endend

Bạn sẽ chú ý lựa chọn key là data. Đây là một lựa chọn nơi chứa cho metadata bạn muốn trả lại khi một item là phù hợp. Đối với trường hợp của chúng tôi, chúng tôi thêm một link tương ứng đến url noun / verb mà sẽ có ích sau này trong các kết quả tìm kiếm sẽ được click.

  1. LOADING DATA INTO REDIS

Bây giờ chúng ta có thể callbacks model tại nơi chúng ta có thể load tất cả các dữ liệu vào Redis bằng cách gọi lưu lại của mỗi record, điều này sẽ kích hoạt callback load_into_soulmate trong model của chúng ta. Chạy rails console và thực hiện như sau:

(Bạn cần chắc chắn rằng bạn đang chạy server redis trước khi chạy các lệnh sau)

$ rails console

2.1.0 :001 > Noun.find_each(&:save)

2.1.0 :001 > Verb.find_each(&:save)

Việc này sẽ lưu lại tất cả các records gây ra callback load_into_soulmate. Cho phép lấy một sneak peek tại các dữ liệu bên trong Redis và làm thế nào nó được lưu bởi soulmate. Trên terminal nhập redis-cli để truy cập console của redis.

$ redis-cli

query redis để lấy các record trong hash soulmate-data của noun và verb đầu tiên tương ứng. Bạn nên làm tương tự:

127.0.0.1:6379> hget soulmate-data:nouns 1

“{“term”:”alarm”,”id”:1,”data”:{“link”:”/nouns/1″}}

127.0.0.1:6379> hget soulmate-data:verbs 1

“{“term”:”calculate”,”id”:1,”data”:{“link”:”/verbs/1″}}”

Từ khoá Redis sử dụng mô hình “soulmate-data:nouns”"soulmate-data:verbs" do tôi đã thêm “nouns”"verbs" như đối số khi gọi class Soulmate::Loader

Chúng ta sẽ được biết các bước tiếp theo để thực hiện Fast Autocomplete Search Terms trong Rails ở bài viết sau.
Tài liệu tham khảo: http://josephndungu.com/tutorials/fast-autocomplete-search-terms-rails

Nguồn: viblo.asia

Bài viết liên quan

WebP là gì? Hướng dẫn cách để chuyển hình ảnh jpg, png qua webp

WebP là gì? WebP là một định dạng ảnh hiện đại, được phát triển bởi Google

Điểm khác biệt giữa IPv4 và IPv6 là gì?

IPv4 và IPv6 là hai phiên bản của hệ thống địa chỉ Giao thức Internet (IP). IP l

Check nameservers của tên miền xem website trỏ đúng chưa

Tìm hiểu cách check nameservers của tên miền để xác định tên miền đó đang dùn

Mình đang dùng Google Domains để check tên miền hàng ngày

Từ khi thông báo dịch vụ Google Domains bỏ mác Beta, mình mới để ý và bắt đầ