journalduhacker/app/models/search.rb

102 lines
2.3 KiB
Ruby
Raw Normal View History

2012-07-12 00:20:43 +02:00
class Search
include ActiveModel::Validations
include ActiveModel::Conversion
include ActiveModel::AttributeMethods
extend ActiveModel::Naming
attr_accessor :q, :what, :order
attr_accessor :results, :page, :total_results, :per_page
validates_length_of :q, :minimum => 2
def initialize
@q = ""
@what = "all"
@order = "relevance"
@page = 1
@per_page = 20
@results = []
@total_results = 0
end
def persisted?
false
end
def to_url_params
2012-09-02 05:52:17 +02:00
[ :q, :what, :order ].map{|p| "#{p}=#{CGI.escape(self.send(p).to_s)}"
2012-07-12 00:20:43 +02:00
}.join("&")
end
2014-01-02 18:16:14 +01:00
def page_count
(total_results.to_i - 1) / per_page.to_i + 1
end
2012-07-12 00:20:43 +02:00
def search_for_user!(user)
opts = {
2014-01-07 11:52:29 +01:00
:ranker => :bm25,
:page => @page,
2012-07-12 00:20:43 +02:00
:per_page => @per_page,
2014-01-07 11:52:29 +01:00
:include => [ :story, :user ],
2012-07-12 00:20:43 +02:00
}
if order == "newest"
2014-01-07 11:52:29 +01:00
opts[:order] = "created_at DESC"
2012-07-12 00:20:43 +02:00
elsif order == "points"
2014-01-07 11:52:29 +01:00
opts[:order] = "score DESC"
2012-07-12 00:20:43 +02:00
end
2014-01-07 11:52:29 +01:00
opts[:classes] = case what
when "all"
[ Story, Comment ]
when what == "comments"
[ Comment ]
when what == "stories"
[ Story ]
else
[]
end
2012-07-12 00:20:43 +02:00
2012-07-12 18:02:00 +02:00
# sphinx seems to interpret slashes as a regex(?) so escape them since
# nobody is probably using them, but don't just use Riddle.escape because
# it removes boolean suport
query = self.q.gsub(/\//, "\\/")
2012-07-12 00:20:43 +02:00
# go go gadget search
2012-09-02 05:52:17 +02:00
@results = []
@total_results = 0
begin
@results = ThinkingSphinx.search query, opts
@total_results = @results.total_entries
rescue => e
Rails.logger.info "Error from Sphinx: #{e.inspect}"
end
2012-07-12 00:20:43 +02:00
# bind votes for both types
if opts[:classes].include?(Comment) && user
votes = Vote.comment_votes_by_user_for_comment_ids_hash(user.id,
@results.select{|r| r.class == Comment }.map{|c| c.id })
@results.each do |r|
if r.class == Comment && votes[r.id]
r.current_vote = votes[r.id]
end
end
end
if opts[:classes].include?(Story) && user
votes = Vote.story_votes_by_user_for_story_ids_hash(user.id,
@results.select{|r| r.class == Story }.map{|s| s.id })
@results.each do |r|
if r.class == Story && votes[r.id]
r.vote = votes[r.id][:vote]
end
end
end
end
end