Rails多模型多字段动态搜索Concern实现需求
我来帮你搞定这个多字段搜索的Concern,刚好之前做过类似需求,直接上代码和详细解释:
实现多字段OR搜索的Rails Concern
首先创建这个Concern文件:
# app/models/concerns/searchable.rb module Searchable extend ActiveSupport::Concern class_methods do def search(query, search_fields: self.search_fields) # 如果查询关键词为空,直接返回所有记录 return all if query.blank? # 为每个搜索字段生成LIKE条件,统一转小写实现大小写不敏感搜索 condition_clauses = search_fields.map do |field| "LOWER(#{table_name}.#{field}) LIKE LOWER(?)" end.join(' OR ') # 绑定参数,避免SQL注入,同时实现模糊匹配 where(condition_clauses, "%#{query}%") end end end
怎么用?
1. 在模型中引入Concern并定义默认搜索字段
比如你的User模型:
# app/models/user.rb class User < ApplicationRecord include Searchable # 定义这个模型默认的搜索字段数组 self.search_fields = ["user_name", "email"] end
2. 在控制器里调用搜索方法
# app/controllers/users_controller.rb def index @users = User.search(params[:query]) end
3. 临时指定搜索字段(可选)
如果某次搜索需要用到不同的字段组合,直接传参数覆盖默认值就行:
# 比如临时搜索用户名和个人简介 @users = User.search(params[:query], search_fields: ["user_name", "bio"])
几个实用细节说明
- 避免SQL注入:这里用了Rails的参数绑定(
?占位符),而不是直接把字符串拼进SQL,绝对安全。 - 表名前缀:条件里加了
#{table_name}.前缀,这样如果你的模型涉及关联查询,不会出现字段名冲突的问题(比如多个表都有title字段)。 - 大小写不敏感:用
LOWER()函数统一转小写,不管用户输入大写还是小写都能匹配到,如果你不需要这个特性,直接去掉LOWER()就行。 - 空查询处理:如果
params[:query]是空的,直接返回所有记录,避免生成无效的SQL语句。
如果你的数据量很大,LIKE查询性能不够的话,可以考虑用PostgreSQL的全文搜索或者Elasticsearch,但这个Concern完全能满足中小数据量的多字段搜索需求~
内容的提问来源于stack exchange,提问作者lilux_m
相关产品推荐
相关产品推荐

