2012-07-11 25 views
1

Im使用will_paginate gem和rails 3.2.3。 我試着去顯示所有具有通過最新帖子訂購某些標記的職位,所以我用這個:Rails 3限制正在搞亂數據庫查詢

@posts = Post.find_by_post_type_label(session[:current_post_type],@selected_labels) 
      .paginate(:page => params[:page], :order => "comments.created_at DESC").all 

但它返回的職位失靈。每個頁面將被排序,但第二頁將有應該在第一個頁面上的帖子。

例子:

Post.find_by_post_type_label(1,[]) 

回報帖[1,2,3,4,5,6,7,8,9,10]分別與那些最新的評論是很多個月以前。它生成的SQL是:

SELECT `posts`.* FROM `posts` WHERE `post`.`post_type_id` = 1 

SELECT `comments`.* FROM `comments` WHERE `comments`.`post_id` IN (1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10) ORDER BY created_at DESC 

如果我爲了它,限制它,雖然,如:

Post.find_by_post_type_label(1,[]).order(comments.created_at DESC).limit(5) 

這是will_paginate是怎麼做的,它返回帖子2,3,4,5,7

產生後:

SELECT DISTINCT `post`.id FROM `posts` LEFT OUTER JOIN 
`comments` ON `comments`.`post_id` = `post`.`id` WHERE 
`post`.`post_type_id` = 1 ORDER BY posts.created_at DESC LIMIT 5 

SELECT `post`.`id` AS t0_r0, `post`.`user_id` AS t0_r1, `post`.`name` AS 
t0_r2, `post`.`image_id` AS t0_r3, `post`.`post_type_id` AS t0_r4, 
`post`.`description` AS t0_r5, `post`.`featured` AS t0_r6, `post`.`approved` 
AS t0_r7, `comment`.`id` AS t1_r0, `comments`.`post_id` AS t1_r1, 
`comments`.`image_id` AS t1_r2, `comments`.`edits` AS t1_r3, 
`comments`.`color` AS t1_r4, `comments`.`min_reputation` AS t1_r5, 
`comments`.`created_at` AS t1_r6, `comments`.`updated_at` AS t1_r7 FROM 
`post` LEFT OUTER JOIN `comments` ON `comments`.`post_id` = 
`post`.`id` WHERE `post`.`post_type_id` = 1 AND `post`.`id` IN (2, 3, 
4, 5, 7) ORDER BY comments.created_at DESC 

這顯然是限制其訂貨前,但我不能弄清楚如何改變這種狀況。 任何幫助,將不勝感激

編輯1

的關係是像這樣:

Class Post 
    belongs_to :user 
    belongs_to :post_type 
    has_many :comments, dependent: :destroy, order: 'created_at DESC' 
    has_and_belongs_to_many :labels 

Class Comment 
    belongs_to :post 
    belongs_to :user 

評論是唯一與數據庫中的時間戳。第一條評論保留了該帖子的時間。

回答

1

卷取在的find_by_sql

SELECT p1.*, iv.created_at FROM posts p1 
INNER JOIN (SELECT p2.id id, max(c.created_at) created_at FROM posts p2 
      INNER JOIN comments c ON c.post_id = p2.id 
      GROUP BY p2.id) 
iv ON p1.id=iv.id ORDER BY iv.created_at DESC LIMIT 5 
0

你應該考慮的方法find_by_sql

所以你可以重新寫這樣的查詢:

ts = Post.find_by_sql("SELECT * FROM posts WHERE post_type_id = ? and id in (?) ORDER BY created_at DESC LIMIT 5", session[:current_post_type], @selected_labels).paginate(:page => params[:page]).all 

我不知道什麼被Post.created_at @selected_labels時,也是這個排序而不是評論,我不知道你爲什麼要按照評論排序帖子...你是否希望首先看到最活躍的帖子?

+0

選中的標籤使用由find_by_type_label過濾帖子使用此SQL。在我的例子中是空白的。我想先顯示最近評論的帖子。通過發佈屬性排序不會對我造成問題,它只有當我嘗試使用嵌套?在限制 – Bishop 2012-07-12 12:57:33

+1

後,您可以分享您的db模式嗎?那麼我們可以編寫一個查詢來完成這個工作。 – hagope 2012-07-12 20:55:54

+0

已更新的原文 – Bishop 2012-07-16 12:56:21