如何使用变量在Ruby中编写查询WIthin A Where子句(PostgreSQL)



这是我希望在不使用gem的情况下实现的。我在我的一个视图上有一个搜索功能,我希望允许人们在一个字段中输入名字和姓氏,让我的类方法同时搜索名字和姓氏并生成一个列表。我目前有以下丑陋的代码,它将在两个字段上进行全文搜索。可怜我吧:)我是SQL和PostgreSQL的新手。我只做了一些基本的查询。

def self.text_search(query)
if query.present?
q1, q2, q3, q4 = query.split(' ')
case
when q4 != nil
where('first_name @@ :q1 OR first_name @@ :q2 OR first_name @@ :q3 OR first_name @@ :q4 OR last_name @@ :q1 OR last_name @@ :q2 OR last_name @@ :q3 OR last_name @@ :q4', q1: q1, q2: q2, q3: q3, q4: q4)
when q3 != nil
where('first_name @@ :q1 OR first_name @@ :q2 OR first_name @@ :q3 OR last_name @@ :q1 OR last_name @@ :q2 OR last_name @@ :q3', q1: q1, q2: q2, q3: q3)
when q2 != nil
where('first_name @@ :q1 OR first_name @@ :q2 OR last_name @@ :q1 OR last_name @@ :q2', q1: q1, q2: q2)
else
where('first_name @@ :q1 OR last_name @@ :q1', q1: q1)
end
else
scoped
end
end

该代码在两个字段中搜索整个单词并生成所有匹配的记录。但是,我想做的是能够从搜索框中输入的值开始搜索列。例如,如果有人输入"Pat",查询将选择Pat、Patrick、Patrice、Patricia等。我相信,即使是我包含的代码,也有更好的编写方法,我可以列出我想检查first_name和last_name的所有值(或者至少我希望有)。

我今天已经做了很多关于这个的网络搜索。我发现了很多关于这方面的信息。我看到了如何使用变量创建正则表达式。这对我来说是显而易见的。我的问题是弄清楚如何将这些信息传递到我的where子句中。例如,我为所有四个字段尝试了以下代码。

qr1 = /^#{q1}/

然后我做了一个类似的where子句,其中我检查了所有四个值的first_name和last_name。我的查询没有返回任何行。

where ('first_name ~ :qr1', qr1: qr1)

我还看到了有关检查子字符串并将其与数组进行比较的解决方案。我看到的这个解决方案的问题是,你必须知道输入的值是多长时间,然后才能成功。下面是一篇Stack Overflow的文章,其中有一个例子:

选择范围中第一个字母的位置(PostgreSQL)

我也看过RailsCasts#343(Pro),其中讨论了to_tsvector和plang_tsquare,但坦率地说,我迷路了。也许这是我的答案,但我肯定需要一些帮助。它对我来说像泥一样清澈。

def self.text_search(query)
if query.present?
arr = query.split(' ').map { |q| "%#{q}" }
where('first_name ~~* ANY(ARRAY[:arr]) OR last_name ~~* ANY(ARRAY[:arr])', arr: arr)
else
scoped
end
end

最新更新