Skip to content

Commit

Permalink
Merge pull request #5627 from avalonmediasystem/timeline_split_search
Browse files Browse the repository at this point in the history
Split query into terms, search each individually, and return intersecion
  • Loading branch information
cjcolvar authored Feb 6, 2024
2 parents ca7a8ca + 51ae04b commit 7ba7773
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 2 deletions.
12 changes: 10 additions & 2 deletions app/models/timeline.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,16 @@ class Timeline < ActiveRecord::Base
belongs_to :user
scope :by_user, ->(user) { where(user_id: user.id) }
# Explicitly cast everything to lowercase for DB agnostic case-insentive search.
scope :title_like, ->(title_filter) { where("LOWER(title) LIKE ?", "%#{title_filter.downcase}%") }
scope :desc_like, ->(desc_filter) { where("LOWER(description) LIKE ?", "%#{desc_filter.downcase}%") }
scope :title_like, ->(title_filter) do
term_array = title_filter.split.map { |term| "%#{sanitize_sql_like(term).downcase}%" }
query = Array.new(term_array.size, "LOWER(title) LIKE ?").join(" AND ")
where(query, *term_array)
end
scope :desc_like, ->(desc_filter) do
term_array = desc_filter.split.map { |term| "%#{sanitize_sql_like(term).downcase}%" }
query = Array.new(term_array.size, "LOWER(description) LIKE ?").join(" AND ")
where(query, *term_array)
end
scope :with_tag, ->(tag_filter) { where("LOWER(tags) LIKE ?", "%\n- #{tag_filter.downcase}\n%") }

validates :user, presence: true
Expand Down
16 changes: 16 additions & 0 deletions spec/models/timeline_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,14 @@
it 'does not return timelines without matching titles' do
expect(Timeline.title_like(title_filter)).not_to include(timeline3)
end
it 'searches on multiple terms' do
expect(Timeline.title_like('Fav Moose')).to include(timeline2)
expect(Timeline.title_like('Fav Moose')).not_to include(timeline1)
expect(Timeline.title_like('Fav Moose')).not_to include(timeline3)
expect(Timeline.title_like('Moose Fav')).to include(timeline2)
expect(Timeline.title_like('Moose Fav')).not_to include(timeline1)
expect(Timeline.title_like('Moose Fav')).not_to include(timeline3)
end
end
describe 'desc_like' do
let(:timeline1) { FactoryBot.create(:timeline, description: 'Moose tunes') }
Expand All @@ -176,6 +184,14 @@
it 'does not return timelines without matching descriptions' do
expect(Timeline.desc_like(desc_filter)).not_to include(timeline3)
end
it 'searches on multiple terms' do
expect(Timeline.desc_like('Fav Moose')).to include(timeline2)
expect(Timeline.desc_like('Fav Moose')).not_to include(timeline1)
expect(Timeline.desc_like('Fav Moose')).not_to include(timeline3)
expect(Timeline.desc_like('Moose Fav')).to include(timeline2)
expect(Timeline.desc_like('Moose Fav')).not_to include(timeline1)
expect(Timeline.desc_like('Moose Fav')).not_to include(timeline3)
end
end
describe 'with_tag' do
let(:timeline1) { FactoryBot.create(:timeline, tags: ['Moose']) }
Expand Down

0 comments on commit 7ba7773

Please sign in to comment.