From: Nguyễn Thái Ngọc Duy Date: Fri, 25 Aug 2006 10:22:14 +0000 (+0700) Subject: Activate Ferret in SearchController. X-Git-Url: https://repo.or.cz/punbbonrails.git/commitdiff_plain/c6d30ca7a56fbfd367fb0d7d23db7e0981d1b3c9 Activate Ferret in SearchController. Added DISTINCT to all id select queries. Quoted forum_id --- diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb index 6185348..bca205b 100644 --- a/app/controllers/search_controller.rb +++ b/app/controllers/search_controller.rb @@ -11,12 +11,27 @@ class SearchController < ApplicationController params[:forum] = nil unless params[:forum] and params[:forum].to_i >= 1 if params.key?(:author) and !params[:author].blank? users = User.get_id_by_username_pattern(params[:author]) - posts = Post.get_id_by_posters(users) + posts_by_author = Post.get_id_by_posters(users) + end + if params.key?(:keywords) and !params[:keywords].blank? + if %w(all message).include? params[:search_in] + posts_by_message = Post.find_id_by_contents(params[:keywords]) + posts_by_message.map! {|x| x[:id].to_i} + end + if %w(all topic).include? params[:search_in] + topics = Topic.find_id_by_contents(params[:keywords]) + topics.map! {|x| x[:id].to_i} + end + end + if posts_by_message.nil? or posts_by_author.nil? + posts = posts_by_author || posts_by_message + else + posts = posts_by_author & posts_by_message end if params[:show_as] == 'posts' - results = Post.get_id_by_posts(posts, current_user, params[:forum]) + results = Post.get_id_by_posts_and_topics(posts, topics, current_user, params[:forum]) else - results = Topic.get_id_by_posts(posts, current_user, params[:forum]) + results = Topic.get_id_by_posts_and_topics(posts, topics, current_user, params[:forum]) end SearchCache.prune result = { diff --git a/app/models/post.rb b/app/models/post.rb index a7871ae..c33c729 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -3,6 +3,7 @@ require 'redcloth' class Post < ActiveRecord::Base belongs_to :poster_user, :class_name => "User", :foreign_key => "poster_id" belongs_to :topic + acts_as_ferret :fields => :message validates_length_of :message, :in => 1..65535 validates_presence_of :topic # is it the rightful way? @@ -85,11 +86,13 @@ class Post < ActiveRecord::Base end def self.get_id_by_posters(posters) - ActiveRecord::Base.connection.select_values("SELECT id FROM posts WHERE poster_id IN(#{posters.map{|x| quote(x)}.join(',')})").map{|x| x.to_i} + ActiveRecord::Base.connection.select_values("SELECT DISTINCT id FROM posts WHERE poster_id IN(#{posters.map{|x| quote(x)}.join(',')})").map{|x| x.to_i} end - def self.get_id_by_posts(posts,user,forum_id = nil) - ActiveRecord::Base.connection.select_values("SELECT t.id FROM posts AS p INNER JOIN topics AS t ON t.id=p.topic_id INNER JOIN forums AS f ON f.id=t.forum_id LEFT JOIN forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id=#{user.group_id}) WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND p.id IN(#{posts.map{|x| quote(x)}.join(',')}) #{'AND t.forum_id='+forum_id unless forum_id.nil?} GROUP BY t.id").map{|x| x.to_i} + def self.get_id_by_posts_and_topics(posts,topics,user,forum_id = nil) + p1 = ActiveRecord::Base.connection.select_values("SELECT DISTINCT p.id FROM posts AS p INNER JOIN topics AS t ON t.id=p.topic_id INNER JOIN forums AS f ON f.id=t.forum_id LEFT JOIN forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id=#{user.group_id}) WHERE (fp.read_forum IS NULL OR fp.read_forum=#{quote(true)}) AND p.id IN(#{posts.map{|x| quote(x)}.join(',')}) #{'AND t.forum_id='+quote(forum_id) unless forum_id.nil?}").map{|x| x.to_i} if posts.is_a? Array + p2 = ActiveRecord::Base.connection.select_values("SELECT DISTINCT MIN(p.id) FROM posts AS p INNER JOIN topics AS t ON t.id=p.topic_id INNER JOIN forums AS f ON f.id=t.forum_id LEFT JOIN forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id=#{user.group_id}) WHERE (fp.read_forum IS NULL OR fp.read_forum=#{quote(true)}) AND t.id in (#{topics.map{|x| quote(x)}.join(',')}) #{'AND t.forum_id='+quote(forum_id) unless forum_id.nil?} GROUP BY t.id").map{|x| x.to_i} if topics.is_a? Array + p1.nil? || p2.nil? ? (p1 || p2) : (p1 + p2).uniq end private diff --git a/app/models/topic.rb b/app/models/topic.rb index 107bf99..66ef826 100644 --- a/app/models/topic.rb +++ b/app/models/topic.rb @@ -2,6 +2,7 @@ class Topic < ActiveRecord::Base # belongs_to :last_post, :class_name => "Post", :foreign_key => "last_post_id" belongs_to :forum has_many :posts, :dependent => :destroy, :order => 'created_at' + acts_as_ferret :fields => :subject validates_presence_of :forum validates_length_of :subject, :in => 1..70 @@ -39,7 +40,7 @@ class Topic < ActiveRecord::Base end def get_post_position(post) - ids = ActiveRecord::Base.connection.select_values("SELECT id FROM posts WHERE topic_id=#{self.id} ORDER BY created_at") + ids = ActiveRecord::Base.connection.select_values("SELECT DISTINCT id FROM posts WHERE topic_id=#{self.id} ORDER BY created_at") ids.map {|i| i.to_i}.index(post.id) end @@ -48,19 +49,20 @@ class Topic < ActiveRecord::Base end def self.get_id_by_user(id,user) - ActiveRecord::Base.connection.select_values("SELECT t.id FROM topics AS t INNER JOIN posts AS p ON t.id=p.topic_id INNER JOIN forums AS f ON f.id=t.forum_id LEFT JOIN forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id=#{user.group_id}) WHERE (fp.read_forum IS NULL OR fp.read_forum=#{quote(true)}) AND p.poster_id=#{user.id} GROUP BY t.id").map{|x| x.to_i} + ActiveRecord::Base.connection.select_values("SELECT DISTINCT t.id FROM topics AS t INNER JOIN posts AS p ON t.id=p.topic_id INNER JOIN forums AS f ON f.id=t.forum_id LEFT JOIN forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id=#{user.group_id}) WHERE (fp.read_forum IS NULL OR fp.read_forum=#{quote(true)}) AND p.poster_id=#{user.id} GROUP BY t.id").map{|x| x.to_i} end def self.get_id_by_time(user,now) - ActiveRecord::Base.connection.select_values("SELECT t.id FROM topics AS t INNER JOIN forums AS f ON f.id=t.forum_id LEFT JOIN forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id=#{user.group_id}) WHERE (fp.read_forum IS NULL OR fp.read_forum=#{quote(true)}) AND t.last_post>#{quote(now)}").map{|x| x.to_i} + ActiveRecord::Base.connection.select_values("SELECT DISTINCT t.id FROM topics AS t INNER JOIN forums AS f ON f.id=t.forum_id LEFT JOIN forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id=#{user.group_id}) WHERE (fp.read_forum IS NULL OR fp.read_forum=#{quote(true)}) AND t.last_post>#{quote(now)}").map{|x| x.to_i} end - def self.get_id_by_posts(posts, user, forum_id = nil) - ActiveRecord::Base.connection.select_values("SELECT t.id FROM posts AS p INNER JOIN topics AS t ON t.id=p.topic_id INNER JOIN forums AS f ON f.id=t.forum_id LEFT JOIN forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id=#{user.group_id}) WHERE (fp.read_forum IS NULL OR fp.read_forum=#{quote(true)}) AND p.id IN(#{posts.map{|x| quote(x)}.join(',')}) #{'AND t.forum_id='+forum_id unless forum_id.nil?} GROUP BY t.id").map{|x| x.to_i} + def self.get_id_by_posts_and_topics(posts, topics, user, forum_id = nil) + p = ActiveRecord::Base.connection.select_values("SELECT DISTINCT t.id FROM posts AS p INNER JOIN topics AS t ON t.id=p.topic_id INNER JOIN forums AS f ON f.id=t.forum_id LEFT JOIN forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id=#{user.group_id}) WHERE (fp.read_forum IS NULL OR fp.read_forum=#{quote(true)}) AND p.id IN(#{posts.map{|x| quote(x)}.join(',')}) #{'AND t.forum_id='+quote(forum_id) unless forum_id.nil?} GROUP BY t.id").map{|x| x.to_i} unless posts.nil? + p.nil? || topics.nil? ? (p || topics) : (p+topics).uniq end def self.get_id_with_no_reply(user) - ActiveRecord::Base.connection.select_values("SELECT t.id FROM topics AS t INNER JOIN forums AS f ON f.id=t.forum_id LEFT JOIN forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id=#{user.group_id}) WHERE (fp.read_forum IS NULL OR fp.read_forum=#{quote(true)}) AND t.num_replies=0 AND t.moved_to IS NULL").map{|x| x.to_i} + ActiveRecord::Base.connection.select_values("SELECT DISTINCT t.id FROM topics AS t INNER JOIN forums AS f ON f.id=t.forum_id LEFT JOIN forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id=#{user.group_id}) WHERE (fp.read_forum IS NULL OR fp.read_forum=#{quote(true)}) AND t.num_replies=0 AND t.moved_to IS NULL").map{|x| x.to_i} end private