mirror of
https://github.com/basecamp/once-campfire.git
synced 2026-10-07 07:10:10 +09:00
6cdcb459b9
The search box keeps only word characters, but FTS5 still reads AND, OR, NOT and NEAR in the query as operators, so searching for "AND" or for "salt AND" raised "fts5: syntax error" and answered with a 500. Quoting each word makes FTS5 look for it as text, which is how it already treats the same words in lower case. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NuTtwJKhb77Dv7EQqv2C3C
37 lines
1.2 KiB
Ruby
37 lines
1.2 KiB
Ruby
module Message::Searchable
|
|
extend ActiveSupport::Concern
|
|
|
|
included do
|
|
after_create_commit :create_in_index
|
|
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 ?", 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
|
|
def create_in_index
|
|
execute_sql_with_binds "insert into message_search_index(rowid, body) values (?, ?)", id, plain_text_body
|
|
end
|
|
|
|
def update_in_index
|
|
execute_sql_with_binds "update message_search_index set body = ? where rowid = ?", plain_text_body, id
|
|
end
|
|
|
|
def remove_from_index
|
|
execute_sql_with_binds "delete from message_search_index where rowid = ?", id
|
|
end
|
|
|
|
def execute_sql_with_binds(*statement)
|
|
self.class.connection.execute self.class.sanitize_sql(statement)
|
|
end
|
|
end
|