如何在Rails Ransack中实现LIKE BINARY大小写敏感搜索?
在Ransack中实现大小写敏感搜索
要在Ransack中实现带BINARY关键字的大小写敏感搜索,核心是自定义Ransack搜索谓词,替代默认的不区分大小写的cont(包含)谓词,具体步骤如下:
1. 在模型中自定义带BINARY的搜索谓词
以你的Customer模型为例,为需要大小写敏感搜索的字段(比如first_name、last_name)定义专属的Ransack谓词:
class Customer < ApplicationRecord # 为first_name定义大小写敏感的包含搜索 ransacker :first_name_binary_cont, formatter: proc { |v| "%#{v}%" } do |parent| # 使用Arel的binary方法添加BINARY关键字,同时处理搜索值避免SQL注入 parent.table[:first_name].binary.matches(Arel.sql("'#{parent.send(:sanitize_sql_like, v)}'")) end # 为last_name定义大小写敏感的包含搜索 ransacker :last_name_binary_cont, formatter: proc { |v| "%#{v}%" } do |parent| parent.table[:last_name].binary.matches(Arel.sql("'#{parent.send(:sanitize_sql_like, v)}'")) end end
2. 修改前端搜索表单的参数名
将原来表单中对应字段的name属性,从默认的q[first_name_cont]/q[last_name_cont]改为我们自定义的q[first_name_binary_cont]/q[last_name_binary_cont]:
<%= search_form_for @q do |f| %> <%= f.label :first_name_binary_cont, "名字(大小写敏感)" %> <%= f.text_field :first_name_binary_cont %> <%= f.label :last_name_binary_cont, "姓氏(大小写敏感)" %> <%= f.text_field :last_name_binary_cont %> <%= f.submit "搜索" %> <% end %>
3. 验证生成的SQL
修改后执行查询,生成的SQL会自动带上BINARY关键字,示例如下:
SELECT `customer`.* FROM `customer` WHERE `customer`.`client_id` = 2 AND (((((BINARY `customer`.`first_name` LIKE '%Hello%') OR (BINARY `customer`.`last_name` LIKE '%Hello%')) ) AND `customer`.`invitation_status` IN ('accepted')) ORDER BY `customer`.`id` ASC LIMIT 10 OFFSET 0
此时搜索"Project"和"project"会返回不同的结果,实现大小写敏感匹配。
内容的提问来源于stack exchange,提问作者IFTEKHAR I ASIF
相关产品推荐
相关产品推荐

