两个灯具:
one:
firstname: John
lastname: Doe
user_id: 1
two:
firstname: Jane
lastname: Doe
user_id: 1
在我的单元测试中,我有以下内容:
test "Searching for a contact gets the right person" do
search = Contact.search("John")
assert_equal 1, search.count
search = Contact.search("Doe")
assert_equal 2, search.count
search = Contact.search("John Doe")
assert_equal 1, search.count
search = Contact.search("John ")
assert_equal 1, search.count
search = Contact.search("Doe John")
assert_equal 1, search.count
end
...最后我调用搜索方法的模型如下:
def self.search(search)
# Check if the search query has more than one word
search_split = search.split(" ")
if search_split.count > 1
# User must be searching for a first and last name
first_word = '%' + search_split[0] + '%'
second_word = '%' + search_split[1] + '%'
conditions = "
firstname ILIKE ? OR lastname ILIKE ?
AND
firstname ILIKE ? OR lastname ILIKE ?",
first_word, first_word, second_word, second_word
where(conditions)
else
# Just searching for a first OR last name
# Strip any whitespace
str = search_split[0]
query = '%' + str + '%'
conditions = "firstname ILIKE ? OR lastname ILIKE ?", query, query
where(conditions)
end
end
除了对“John Doe”进行测试的测试外,所有测试都通过。它实际上也最终拉了“Jane Doe”。
我认为在邻接的AND之前调用两个OR有一些优先级问题,但它是否能理解我想要完成的事情?
我还没到我正在重构的那一刻;只是想要变绿,这样我才能继续前进。感谢您提前提供任何帮助!
答案 0 :(得分:3)
您需要进行一些重组才能获得您所追求的逻辑:
conditions = "
(firstname ILIKE ? AND lastname ILIKE ?)
OR
(firstname ILIKE ? AND lastname ILIKE ?)",
first_word, second_word, second_word, first_word
当你打电话时,那应该与“John Doe”和“Doe John”匹配,而不是“Jane Doe”:
Contact.search('Jo Do')
你实际上并不需要括号,因为布尔代数中的AND has a higher precedence than OR(以及SQL的逻辑是based on Boolean Algebra)但是没有充分的理由不包括它们。