49 lines
1.1 KiB
Ruby
49 lines
1.1 KiB
Ruby
module Card::Searchable
|
|
extend ActiveSupport::Concern
|
|
|
|
included do
|
|
include ::Searchable
|
|
|
|
searchable_by :title_and_description, using: :cards_search_index, as: :title
|
|
|
|
scope :mentioning, ->(query) do
|
|
if query = sanitize_query_syntax(query)
|
|
cards = Card.search(query).select(:id).to_sql
|
|
comments = Comment.search(query).select(:id).to_sql
|
|
|
|
left_joins(:comments).where("cards.id in (#{cards}) or comments.id in (#{comments})").distinct
|
|
else
|
|
none
|
|
end
|
|
end
|
|
end
|
|
|
|
class_methods do
|
|
def sanitize_query_syntax(terms)
|
|
terms = terms.to_s
|
|
terms = remove_invalid_search_characters(terms)
|
|
terms = remove_unbalanced_quotes(terms)
|
|
terms.presence
|
|
end
|
|
|
|
private
|
|
def remove_invalid_search_characters(terms)
|
|
terms.gsub(/[^\w"]/, " ")
|
|
end
|
|
|
|
def remove_unbalanced_quotes(terms)
|
|
if terms.count("\"").even?
|
|
terms
|
|
else
|
|
terms.gsub("\"", " ")
|
|
end
|
|
end
|
|
end
|
|
|
|
private
|
|
# TODO: Temporary until we stabilize the search API
|
|
def title_and_description
|
|
[ title, description.to_plain_text ].join(" ")
|
|
end
|
|
end
|