作者:告非言普 | 来源:互联网 | 2023-05-26 15:29
我有一个值数组:
words = ['foo', 'bar', 'baz']
我想用LIKE(而不是"IN")自动生成where子句.
我现在做的是:
words = params[:content].split(' ').map { |w| "%#{w.strip}%" }
where = []
words.size.times do
where <<'name LIKE ?'
end
tags = Tag.where(where.join(' OR '), *words)
SQL生成的正确请求:
SELECT `tags`.* FROM `tags` WHERE (name LIKE '%foo%' OR name LIKE '%bar%' OR name LIKE '%baz%')
但这不是真正好的方式......
当我想用equals比较数组值时,我们可以这样做:
Tag.where(name: words)
有可能做同样的事情,但不生成IN
,但多个OR LIKE "%VALUE%"
?怎么样?
1> Laurens..:
在postgresql中它的工作原理如下:
Tag.where("name iLIKE ANY ( array[?] )", words)
SQL RLIKE(REGEX)
Tag.where("name RLIKE ?", words.join("|"))
SQL select(效率不高):
Tag.select{ |c| c.name =~ Regexp.new(words.join("|"), true) }
作为Tag.rb中的范围(SQL)
scope :ilike_any, -> (words) { where("name RLIKE ?", words.join("|")) }
这使您可以:
words = %w(word1 word2 word3)
Tag.ilike_any(words)