Skip to content

Commit

Permalink
filter by tag and domain when searching for comments
Browse files Browse the repository at this point in the history
  • Loading branch information
david-wolgemuth authored and pushcx committed Aug 15, 2018
1 parent 86ac988 commit c1681a4
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 20 deletions.
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,5 @@ group :test, :development do
gem "sqlite3"
gem "faker"
gem "byebug"
gem "rb-readline"
end
2 changes: 2 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ GEM
rb-fsevent (0.10.3)
rb-inotify (0.9.10)
ffi (>= 0.5.0, < 2)
rb-readline (0.5.5)
rotp (3.3.1)
rqrcode (0.10.1)
chunky_png (~> 1.0)
Expand Down Expand Up @@ -241,6 +242,7 @@ DEPENDENCIES
nokogiri (>= 1.7.2)
oauth
rails (~> 5.2.0)
rb-readline
rotp
rqrcode
rspec-rails
Expand Down
48 changes: 29 additions & 19 deletions app/models/search.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,23 @@ def with_tags(base, tag_scopes)
.group("stories.id")
end

def with_stories_in_domain(base, domain)
begin
reg = Regexp.new("//([^/]*\.)?#{domain}/")
base.where("`stories`.`url` REGEXP '" +
ActiveRecord::Base.connection.quote_string(reg.source) + "'")
rescue RegexpError
return base
end
end

def with_stories_matching_tags(base, tag_scopes)
story_ids_matching_tags = with_tags(
Story.unmerged.where(:is_expired => false), tag_scopes
).select(:id).map(&:id)
base.where(story_id: story_ids_matching_tags)
end

def search_for_user!(user)
self.results = []
self.total_results = 0
Expand All @@ -84,13 +101,7 @@ def search_for_user!(user)
when "stories"
base = Story.unmerged.where(:is_expired => false)
if domain.present?
begin
reg = Regexp.new("//([^/]*\.)?#{domain}/")
base = base.where("`url` REGEXP '" +
ActiveRecord::Base.connection.quote_string(reg.source) + "'")
rescue RegexpError
return false
end
base = with_stories_in_domain(base, domain)
end

title_match_sql = Arel.sql("MATCH(stories.title) AGAINST('#{qwords}' IN BOOLEAN MODE)")
Expand Down Expand Up @@ -138,17 +149,20 @@ def search_for_user!(user)
end

when "comments"
base = Comment.active.where(Arel.sql("MATCH(comment) AGAINST('#{qwords}' IN BOOLEAN MODE)"))
.includes(:user, :story)

base = Comment.active
if domain.present?
base = with_stories_in_domain(base.joins(:story), domain)
end
if tag_scopes.present?
base = with_stories_matching_tags(base, tag_scopes)
end
if qwords.present?
base = base.where(Arel.sql("MATCH(comment) AGAINST('#{qwords}' IN BOOLEAN MODE)"))
end
self.results = base.select(
"comments.*, " +
"MATCH(comment) AGAINST('#{qwords}' IN BOOLEAN MODE) AS rel_comment"
)

if tag_scopes.present?
self.results = with_tags(base, tag_scopes)
end
).includes(:user, :story)

case self.order
when "relevance"
Expand All @@ -158,12 +172,8 @@ def search_for_user!(user)
when "points"
self.results.order!("#{Comment.score_sql} DESC")
end
end

if tag_scopes.present?
self.total_results = self.results.length
else
self.total_results = base.count
end

if self.page > self.page_count
Expand Down
70 changes: 69 additions & 1 deletion spec/models/search_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,29 @@
:user_id => @user.id,
:tags_a => ["tag1"]),
]
@comments = [
create(:comment, :comment => "comment0",
:story_id => @multi_tag.id,
:user_id => @user.id),
create(:comment, :comment => "comment1",
:story_id => @stories[0].id,
:user_id => @user.id),
create(:comment, :comment => "comment2",
:story_id => @stories[1].id,
:user_id => @user.id),
create(:comment, :comment => "comment3",
:story_id => @stories[2].id,
:user_id => @user.id),
create(:comment, :comment => "comment4",
:story_id => @stories[4].id,
:user_id => @user.id),
]
end

after(:all) do
@user.destroy!
@comments.each(&:destroy!)
@stories.each(&:destroy!)
@user.destroy! if @user
end

it "can search for stories" do
Expand Down Expand Up @@ -103,4 +121,54 @@

expect(search.results.length).to eq(2)
end

it "can search for comments" do
search = Search.new
search.q = "comment1"
search.what = "comments"

search.search_for_user!(@user)

expect(search.results).to include(@comments[1])
end
it "can search for comments by tag" do
search = Search.new
search.q = "comment2 comment3 tag:tag1"
search.what = "comments"

search.search_for_user!(@user)

expect(search.results).to include(@comments[2])
expect(search.results).not_to include(@comments[3])
end
it "can search for comments with only tags" do
search = Search.new
search.q = "tag:tag1"
search.what = "comments"

search.search_for_user!(@user)

expect(search.results).to include(@comments[2])
expect(search.results).not_to include(@comments[3])
end
it "should only return comments matching all tags if multiple are present" do
search = Search.new
search.q = "tag:tag1 tag:tag2"
search.what = "comments"

search.search_for_user!(@user)

expect(search.results).to eq([@comments[0]])
end

it "should only return comments with stories in domain if domain present" do
search = Search.new
search.q = "comment3 comment4 domain:lobste.rs"
search.what = "comments"

search.search_for_user!(@user)

expect(search.results).to include(@comments[4])
expect(search.results).not_to include(@comments[3])
end
end

0 comments on commit c1681a4

Please sign in to comment.