oka*_*56k 1 ruby postgresql ruby-on-rails ruby-on-rails-5
假设我有这样的范围:
scope :by_templates, ->(t) { joins(:template).where('templates.label ~* ?', t) }
Run Code Online (Sandbox Code Playgroud)
如何检索多个模板t
?
Document.first.by_templates(%w[email facebook])
Run Code Online (Sandbox Code Playgroud)
此代码返回此错误.
PG::DatatypeMismatch: ERROR: argument of AND must be type boolean, not type record
LINE 1: ...template_id" WHERE "documents"."user_id" = $1 AND (templates...
Run Code Online (Sandbox Code Playgroud)
PostgreSQL允许您使用op any(array_expr)
构造将一个布尔值运算符应用于整个值数组:
9.23.3.ANY/SOME(数组)
Run Code Online (Sandbox Code Playgroud)expression operator ANY (array expression) expression operator SOME (array expression)
右侧是带括号的表达式,它必须产生一个数组值.评估左侧表达式并使用给定的数组的每个元素进行比较
operator
,这必须产生布尔结果.ANY
如果获得任何真实结果,则结果为"真".如果未找到真实结果,则结果为"假"(包括阵列具有零元素的情况).
PostgreSQL还支持用于创建数组的数组构造函数语法:
array[value, value, ...]
Run Code Online (Sandbox Code Playgroud)
方便的是,当值是数组时,ActiveRecord会将占位符扩展为逗号分隔的列表.
把这些放在一起给了我们:
scope :by_templates, ->(templates) { joins(:template).where('templates.label ~* any(array[?])', templates) }
Run Code Online (Sandbox Code Playgroud)
顺便说一下,如果你使用不区分大小写的regex operator(~*
)作为不区分大小写的比较(即没有真正的正则表达式模式匹配),那么你可能想要使用upper
:
# Yes, this class method is still a scope.
def self.by_templates(templates)
joins(:template).where('upper(templates.label) = any(array[?])', templates.map(&:upcase) }
end
Run Code Online (Sandbox Code Playgroud)
然后,你可以添加一个索引来templates
上upper(label)
加快速度,并避免与杂散正则表达式元字符可能存在的问题templates
.我倾向于使用大写对于这样的事情,因为古怪的谎言'ß'.upcase
是'SS'
,但'SS'.downcase
作为'ss'
.
归档时间: |
|
查看次数: |
53 次 |
最近记录: |