2012-03-11 72 views
0

我有一個型號:如何按最後評論的日期排序,並按上次創建的順序排序?

class Post < ActiveRecord::Base 
    attr_accessible :title, :content, :tag_names 

    belongs_to :user 

    has_many :comments, :dependent => :destroy 
end 

    belongs_to :post, :counter_cache => true 
    belongs_to :user 
end 

評論型號:

class Comment < ActiveRecord::Base 
    attr_accessible :content, :user_id 

    belongs_to :post, :counter_cache => true 
    belongs_to :user 
end 

現在我知道如何按日期排序:created_at ASCcreated_at DESC

現在我想知道,如何按最後一條評論的日期排序並按上次創建的順序排序?

幾乎StackOverflow是如何做的。例如,如果問題得到回覆,則將其置於頂部,如果回答了其他問題,則將該問題置於頂部,依此類推。否則,問題將按ASC排序。

生成的SQL:

Started POST "/posts/30/comments" for 127.0.0.1 at 2012-03-12 11:59:32 +0800 
Processing by CommentsController#create as HTML 
    Parameters: {"utf8"=>"✓", "authenticity_token"=>"0zGpin7T/1aH/JBomGiqsEYCIgQ04HQWHZ/bIjm7WKs=", "comment"=>{"content"=>"sfsfwfewsdesd"}, "commit"=>"Create Comment", "post_id"=>"30"} 
    Post Load (0.3ms) SELECT "posts".* FROM "posts" WHERE "posts"."id" = ? LIMIT 1 [["id", "30"]] 
    User Load (0.6ms) SELECT "users".* FROM "users" WHERE "users"."id" = 2 LIMIT 1 
    (0.2ms) begin transaction 
    SQL (1.1ms) INSERT INTO "comments" ("content", "created_at", "post_id", "total_votes", "updated_at", "user_id") VALUES (?, ?, ?, ?, ?, ?) [["content", "sfsfwfewsdesd"], ["created_at", Mon, 12 Mar 2012 03:59:32 UTC +00:00], ["post_id", 30], ["total_votes", 0], ["updated_at", Mon, 12 Mar 2012 03:59:32 UTC +00:00], ["user_id", 2]] 
    Post Load (0.4ms) SELECT "posts".* FROM "posts" WHERE "posts"."id" = 30 LIMIT 1 
    SQL (0.5ms) UPDATE "posts" SET "comments_count" = COALESCE("comments_count", 0) + 1 WHERE "posts"."id" = 30 
    (130.3ms) commit transaction 
Redirected to http://localhost:3000/posts/30 
Completed 302 Found in 156ms (ActiveRecord: 133.4ms) 

回答

2

首先,你需要另外一個DateTime列添加到您的文章。我們稱之爲content_changed_at或類似的東西。在一篇新文章中,它的值爲created_at。然後,每當評論發佈時更新它。當您需要顯示帖子時,您只需按此欄對其進行排序。

這是未經測試的代碼,但它應該給你的想法。

class Post < ActiveRecord::Base 
    attr_accessible :title, :content, :tag_names 

    before_create :init_sort_column 

    belongs_to :user 

    has_many :comments, :dependent => :destroy 

    private 
    def init_sort_column 
    self.content_changed_at = self.created_at || Time.now 
    end 
end 

    belongs_to :post, :counter_cache => true 
    belongs_to :user 
end 

class Comment < ActiveRecord::Base 
    attr_accessible :content, :user_id 

    after_create :update_parent_sort_column 

    belongs_to :post, :counter_cache => true 
    belongs_to :user 

    private 
    def update_parent_sort_column 
    if post 
     post.content_changed_at = self.created_at 
    end 
    end 
end 
+0

我一定要創建content_changed_at列或使用'attr_accessor'或'某處attr_writer'?因爲我得到這個錯誤:'未定義的方法'content_changed_at ='for#' – alexchenco 2012-03-11 12:18:35

+0

您需要數據庫中的實列。一個普通的日期時間列。 – 2012-03-11 12:19:59

+0

所以遷移應該是'add_column:posts,:content_changed_at,:datetime'? – alexchenco 2012-03-11 12:25:06

6

如果我是你,我會一個last_comment_at補充:時間字段來安置自己的模式,一定要更新每當創建的評價是日期時間。

這種方式,您可以簡單地使用Post.order('last_comment_at, created_at DESC')

更新 - 回覆您的留言詢問你需要遷移,以下應爲您生成遷移:

rails generate migration add_last_comment_at_to_posts last_comment_at:datetime 

正如其他有請注意,您可以在評論模型中添加after_save調用,以更新Post模型中的last_comment_at字段。我會用這樣的:

class Comment < ActiveRecord::Base 
    belongs_to :post 

    after_save :update_post_last_comment_at 

    private 

    def update_post_last_comment_at 
    self.post.touch(:last_comment_at) if self.post 
    end 
end 
+0

你能否給我更多關於在遷移文件中添加什麼的細節? – alexchenco 2012-03-11 12:12:00

+0

查看我的回答中的更新:) – Jon 2012-03-11 16:21:40

相關問題