Activate Ferret in SearchController.
authorNguyễn Thái Ngọc Duy <[email protected]>
Fri, 25 Aug 2006 10:22:14 +0000 (25 17:22 +0700)
committerNguyễn Thái Ngọc Duy <[email protected]>
Fri, 25 Aug 2006 10:22:14 +0000 (25 17:22 +0700)
Added DISTINCT to all id select queries.
Quoted forum_id

app/controllers/search_controller.rb
app/models/post.rb
app/models/topic.rb

index 6185348..bca205b 100644 (file)
@@ -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 = {
index a7871ae..c33c729 100644 (file)
@@ -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
index 107bf99..66ef826 100644 (file)
@@ -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