Postgres LIKE在Rails应用程序中

Gur*_*ngh 3 ruby postgresql ruby-on-rails ruby-on-rails-4 rails-activerecord

我有这样的Postgres LIKE声明:

@favorites.find_each do |profiles|
  @related_profiles = Profile.where('name LIKE ?', '%' + profiles.name + '%')
end
Run Code Online (Sandbox Code Playgroud)

我正在尝试做的是遍历favourites变量,并找到带有contain某些名称字符的所有配置文件。

例如,"jasson jackson"如果名称包含"jackson""jasson"

ore*_*uwa 5

您要查找的查询将像:

Profile.where("name LIKE ?", "%#{profiles.name}%")
Run Code Online (Sandbox Code Playgroud)

但是请注意,@related_profiles可能未正确分配您的姓名,因为结果与以下说法相同:

Profile.where("name LIKE ?", "%#{@favorites.last.name}%")
Run Code Online (Sandbox Code Playgroud)

而我怀疑那是否是您所需要的。还要注意,它将是一个ActiveRecord :: Collection,类似于对象的数组。

解决该问题的一种方法是初始化@related_profiles = [],然后在循环的每个点执行以下操作:

@related_profiles += 
Profile.where("name LIKE ?", "%#{profiles.name}%")
Run Code Online (Sandbox Code Playgroud)

或另一种方式是:

names = @favorites.map(&:name)
query = names.map{|name| "name LIKE '%#{name}%'"}.join(" OR ")
Run Code Online (Sandbox Code Playgroud)

要么

query = @favorites.map{|favorite| "name LIKE '%#{favorite.name}%'" }.join(" OR ")
Run Code Online (Sandbox Code Playgroud)

然后

profiles = Profile.where(query)
Run Code Online (Sandbox Code Playgroud)

更新 基于@joshrumbut的评论,我决定使用bind参数重新实现。但是,代码的清晰性有些丢失,但是可以通过以下方式实现:

names = @favorites.map(&:name)
query = names.map{|favorite| "name LIKE ?" }.join(" OR ")
profiles = Profile.where(query, *names.map{|name| ("%#{name}%")})
Run Code Online (Sandbox Code Playgroud)

根据@muistooshort的评论,我删除了前两个查询中的引号,我认为这种方法看起来更干净,正如他建议的那样。来自文档

Profile.where('name like any(array[?])', names.map { |s| "%#{s}%" })
Run Code Online (Sandbox Code Playgroud)