mirror of
https://github.com/basecamp/once-campfire.git
synced 2026-10-07 07:10:10 +09:00
Merge pull request #298 from namespaceMarcello/search-operator-words
Search for operator words instead of parsing them
This commit is contained in:
@@ -6,7 +6,15 @@ module Message::Searchable
|
||||
after_update_commit :update_in_index
|
||||
after_destroy_commit :remove_from_index
|
||||
|
||||
scope :search, ->(query) { joins("join message_search_index idx on messages.id = idx.rowid").where("idx.body match ?", query).ordered }
|
||||
scope :search, ->(query) { joins("join message_search_index idx on messages.id = idx.rowid").where("idx.body match ?", match_terms(query)).ordered }
|
||||
end
|
||||
|
||||
class_methods do
|
||||
# Quotes each word, so that FTS5 searches for AND, OR, NOT and NEAR rather than
|
||||
# parsing them as operators, which fails on a query like "AND" or "salt AND".
|
||||
def match_terms(query)
|
||||
query.split.map { |word| %("#{word.gsub('"', '""')}") }.join(" ")
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@@ -20,6 +20,24 @@ class SearchesControllerTest < ActionDispatch::IntegrationTest
|
||||
assert_select ".message", text: /Hello world!/
|
||||
end
|
||||
|
||||
test "operator words are searched for as words" do
|
||||
rooms(:designers).messages.create! body: "Salt and pepper", client_message_id: "operators", creator: users(:david)
|
||||
|
||||
get searches_url, params: { q: "salt AND" }
|
||||
|
||||
assert_response :success
|
||||
assert_select ".message", text: /Salt and pepper/
|
||||
end
|
||||
|
||||
test "searching for an operator word alone doesn't fail" do
|
||||
%w[ AND OR NOT ].each do |word|
|
||||
get searches_url, params: { q: word }
|
||||
|
||||
assert_response :success
|
||||
assert_select ".message", count: 0
|
||||
end
|
||||
end
|
||||
|
||||
test "unreachable messages are not found" do
|
||||
memberships(:david_designers).destroy!
|
||||
|
||||
|
||||
@@ -65,6 +65,12 @@ class MessageTest < ActiveSupport::TestCase
|
||||
assert_equal room.messages.ordered.first(Message::Pagination::PAGE_SIZE).map(&:id), room.messages.first_page.map(&:id)
|
||||
end
|
||||
|
||||
test "search reads quotes and operator words in the query as text" do
|
||||
message = rooms(:designers).messages.create!(body: "Say hi, NOT bye", client_message_id: "quoted", creator: users(:david))
|
||||
|
||||
assert_equal [ message ], Message.search(%(say "hi NOT)).to_a
|
||||
end
|
||||
|
||||
private
|
||||
def create_new_message_in(room)
|
||||
room.messages.create!(creator: users(:jason), body: "Hello", client_message_id: "123")
|
||||
|
||||
Reference in New Issue
Block a user