Rails 8中添加了很多SQLite的功能,而且全都是生产可用的级别,比如非常有用的fts, 也就是full-text search,对于中小型应用相当好用,不用再单独起一个服务。
但该功能全网还没有任何教程或者信息,包括rails官方文档也暂时没有更新,所以只能查代码和一个该功能的PR
以下是配置fts的基本步骤,供参考:
场景:给博客应用添加搜索功能,索引标题(title)和内容(content),其中content是rich text类型
- 手动创建迁移文件
bin/rails g migrate CreateVirtualArticleFts
内容如下:class CreateVirtualArticleFts < ActiveRecord::Migration[8.0] def change create_virtual_table :article_fts, :fts5, ["content", "title"] end end
- 创建model文件
app/models/article_fts.rb
class ArticleFts < ApplicationRecord self.primary_key = "rowid" # 虚拟表只能使用rowid end
-
创建
app/models/concerns/article/full_text_search.rb
文件module Article::FullTextSearch extend ActiveSupport::Concern included do has_one :article_fts, foreign_key: "rowid" end class_methods do def full_text_search(input:, limit:) where("article_fts.title LIKE ? OR article_fts.content LIKE ?", "%#{input}%", "%#{input}%") .joins(:article_fts) .limit(limit) .distinct end end def find_or_create_article_fts return if article_fts sql = ActiveRecord::Base.sanitize_sql_array( [ "INSERT INTO article_fts (rowid, title, content) VALUES (?, ?, ?)", id, title || "", content.to_plain_text ] ) ActiveRecord::Base.connection.execute(sql) end end
- 在
app/models/article.rb
模型中添加导入和回调函数include Article::FullTextSearch after_save :find_or_create_article_fts
- 在
app/controllers/article_controller.rb
使用搜索参数@per_page = 10 @articles = if params[:q].present? Article.full_text_search( input: params[:q], limit: @per_page )
- 添加搜索框的前端代码
<%= form_tag root_path, method: :get, class: 'search-form' do %> <%= search_field_tag :q, params[:q], placeholder: 'Search...' %> <%= submit_tag 'Search' %> <% end %>
最后重新
db:migrate
后就可用了