Files
once-campfire/app/models/message/searchable.rb
T
Marcello Costagliola 6cdcb459b9 Search for operator words instead of parsing them
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
2026-10-05 01:08:53 +02:00

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