5
3
mirror of https://github.com/tildeverse/lobsters synced 2024-06-15 05:26:35 +00:00

filter by tag and domain when searching for comments

This commit is contained in:
David Wolgemuth 2018-06-11 18:28:11 -05:00 committed by Peter Bhat Harkins
parent 86ac9887b8
commit c1681a4063
4 changed files with 101 additions and 20 deletions

View File

@ -47,4 +47,5 @@ group :test, :development do
gem "sqlite3" gem "sqlite3"
gem "faker" gem "faker"
gem "byebug" gem "byebug"
gem "rb-readline"
end end

View File

@ -153,6 +153,7 @@ GEM
rb-fsevent (0.10.3) rb-fsevent (0.10.3)
rb-inotify (0.9.10) rb-inotify (0.9.10)
ffi (>= 0.5.0, < 2) ffi (>= 0.5.0, < 2)
rb-readline (0.5.5)
rotp (3.3.1) rotp (3.3.1)
rqrcode (0.10.1) rqrcode (0.10.1)
chunky_png (~> 1.0) chunky_png (~> 1.0)
@ -241,6 +242,7 @@ DEPENDENCIES
nokogiri (>= 1.7.2) nokogiri (>= 1.7.2)
oauth oauth
rails (~> 5.2.0) rails (~> 5.2.0)
rb-readline
rotp rotp
rqrcode rqrcode
rspec-rails rspec-rails

View File

@ -61,6 +61,23 @@ class Search
.group("stories.id") .group("stories.id")
end 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) def search_for_user!(user)
self.results = [] self.results = []
self.total_results = 0 self.total_results = 0
@ -84,13 +101,7 @@ class Search
when "stories" when "stories"
base = Story.unmerged.where(:is_expired => false) base = Story.unmerged.where(:is_expired => false)
if domain.present? if domain.present?
begin base = with_stories_in_domain(base, domain)
reg = Regexp.new("//([^/]*\.)?#{domain}/")
base = base.where("`url` REGEXP '" +
ActiveRecord::Base.connection.quote_string(reg.source) + "'")
rescue RegexpError
return false
end
end end
title_match_sql = Arel.sql("MATCH(stories.title) AGAINST('#{qwords}' IN BOOLEAN MODE)") title_match_sql = Arel.sql("MATCH(stories.title) AGAINST('#{qwords}' IN BOOLEAN MODE)")
@ -138,17 +149,20 @@ class Search
end end
when "comments" when "comments"
base = Comment.active.where(Arel.sql("MATCH(comment) AGAINST('#{qwords}' IN BOOLEAN MODE)")) base = Comment.active
.includes(:user, :story) 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( self.results = base.select(
"comments.*, " + "comments.*, " +
"MATCH(comment) AGAINST('#{qwords}' IN BOOLEAN MODE) AS rel_comment" "MATCH(comment) AGAINST('#{qwords}' IN BOOLEAN MODE) AS rel_comment"
) ).includes(:user, :story)
if tag_scopes.present?
self.results = with_tags(base, tag_scopes)
end
case self.order case self.order
when "relevance" when "relevance"
@ -158,12 +172,8 @@ class Search
when "points" when "points"
self.results.order!("#{Comment.score_sql} DESC") self.results.order!("#{Comment.score_sql} DESC")
end end
end
if tag_scopes.present?
self.total_results = self.results.length self.total_results = self.results.length
else
self.total_results = base.count
end end
if self.page > self.page_count if self.page > self.page_count

View File

@ -31,11 +31,29 @@ describe Search do
:user_id => @user.id, :user_id => @user.id,
:tags_a => ["tag1"]), :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 end
after(:all) do after(:all) do
@user.destroy! @comments.each(&:destroy!)
@stories.each(&:destroy!) @stories.each(&:destroy!)
@user.destroy! if @user
end end
it "can search for stories" do it "can search for stories" do
@ -103,4 +121,54 @@ describe Search do
expect(search.results.length).to eq(2) expect(search.results.length).to eq(2)
end 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 end