Ernie/Ransack 项目中的谓词(Predicates)使用指南
ransack 项目地址: https://gitcode.com/gh_mirrors/ran/ransack
前言
在 Ernie/Ransack 项目中,谓词(Predicates)是构建搜索查询的核心元素。作为 Ruby on Rails 生态中强大的搜索解决方案,Ransack 通过谓词提供了灵活且直观的方式来构建复杂的数据库查询。本文将全面介绍 Ransack 中各种谓词的使用方法及其应用场景。
谓词基础概念
谓词是附加在模型属性名后的后缀,用于指定搜索条件的匹配方式。它们构成了 Ransack 查询 DSL 的基础语法。例如:
User.ransack(first_name_cont: 'John')
这里的 _cont
就是一个谓词,表示"包含"的匹配条件。
常用谓词详解
1. 相等性匹配
eq (equals) 谓词
精确匹配字段值:
User.ransack(first_name_eq: 'John').result.to_sql
# => SELECT "users".* FROM "users" WHERE "users"."first_name" = 'John'
not_eq 谓词
不匹配指定值:
User.ransack(first_name_not_eq: 'John').result.to_sql
2. 字符串匹配
cont (contains) 谓词
包含指定字符串(使用通配符):
User.ransack(first_name_cont: 'oh').result.to_sql
# => SELECT ... WHERE ("users"."first_name" LIKE '%oh%')
start 和 end 谓词
匹配开头或结尾:
User.ransack(first_name_start: 'Jo').result.to_sql # 查找以'Jo'开头的名字
User.ransack(first_name_end: 'hn').result.to_sql # 查找以'hn'结尾的名字
3. 数值比较
lt/lteq/gt/gteq 谓词
数值比较操作:
User.ransack(age_lt: 30).result.to_sql # 年龄小于30
User.ransack(age_lteq: 30).result.to_sql # 年龄小于等于30
User.ransack(age_gt: 18).result.to_sql # 年龄大于18
User.ransack(age_gteq: 18).result.to_sql # 年龄大于等于18
4. 集合操作
in 谓词
匹配值列表中的任意一个:
User.ransack(age_in: [18, 21, 25]).result.to_sql
# => SELECT ... WHERE "users"."age" IN (18, 21, 25)
cont_any 和 cont_all 谓词
高级字符串包含操作:
# 包含任意一个指定词
User.ransack(bio_cont_any: ['ruby', 'rails']).result.to_sql
# 包含所有指定词
User.ransack(bio_cont_all: ['senior', 'developer']).result.to_sql
5. 布尔值操作
true/false 谓词
布尔字段查询:
User.ransack(active_true: '1').result.to_sql # 查找活跃用户
User.ransack(active_false: '1').result.to_sql # 查找非活跃用户
6. 空值检查
null/present 谓词
检查字段是否为空:
User.ransack(email_null: '1').result.to_sql # 邮箱为NULL
User.ransack(email_present: '1').result.to_sql # 邮箱不为空
高级用法
组合查询
Ransack 支持通过 _or_
连接符组合多个条件:
# 查找名字或姓氏包含指定字符串的用户
User.ransack(first_name_or_last_name_cont: 'smith').result.to_sql
关联模型查询
查询关联模型的属性:
# 假设User has_many :posts
User.ransack(posts_title_cont: 'Rails').result.to_sql
大小写不敏感查询
使用 i_cont
等前缀为 i_
的谓词进行大小写不敏感查询:
User.ransack(first_name_i_cont: 'john').result.to_sql
# 会匹配"John"、"JOHN"、"john"等
注意事项
-
字段存在性检查:如果使用不存在的字段进行查询,Ransack 会静默忽略该条件而不会报错。
-
数据库差异:某些谓词的行为可能因底层数据库而异,特别是大小写敏感性和布尔值表示。
-
性能考虑:使用通配符开头的LIKE查询(如
%text
)通常无法使用索引,在大数据量时可能影响性能。
URL参数结构
在Web应用中,Ransack查询参数通常以以下格式传递:
/users?q[first_name_cont]=john&q[age_gt]=18&q[s]=created_at+desc
对应的JavaScript请求示例:
fetch('/users.json', {
method: 'GET',
params: {
q: {
first_name_cont: 'john',
age_gt: 18,
s: 'created_at desc'
}
}
})
总结
Ransack 的谓词系统提供了强大而灵活的方式来构建各种查询条件。通过合理组合不同的谓词,开发者可以轻松实现复杂的搜索功能,而无需编写复杂的SQL语句。掌握这些谓词的使用方法,将极大提升在Ruby on Rails应用中的搜索功能开发效率。
ransack 项目地址: https://gitcode.com/gh_mirrors/ran/ransack
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考