简体   繁体   English

如何按最后评论的日期排序,并按最后创建的日期排序?

[英]How to order by the date of the last comment and sort by last created otherwise?

I have a Post model: 我有一个Post模型:

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

and a Comment model: 评论模型:

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

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

Right now I know how to sort by date: created_at ASC , created_at DESC . 现在,我知道如何按日期排序: created_at ASCcreated_at DESC

Now I would like to know, how to order by the date of the last comment and sort by last created otherwise? 现在,我想知道,如何按最后评论的日期排序,并按最后创建的排序?

Pretty much how StackOverflow does. StackOverflow的功能差不多。 For instance, if a question gets replied it is placed at the top, if other question is replied this one is placed on the top and so on. 例如,如果一个问题得到答复,则该问题位于顶部,如果其他问题得到答复,则该问题位于顶部,依此类推。 Questions are sorted ASC otherwise. 否则,问题按ASC排序。

Generated SQL: 生成的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) 

If I were you I would add a last_comment_at:datetime field to your Post model, and be sure to update that datetime whenever a comment is created. 如果您是我,我会在您的Post模型中添加一个last_comment_at:datetime字段,并确保在创建注释时更新该datetime。

This way you can simply use Post.order('last_comment_at, created_at DESC') 这样,您可以简单地使用Post.order('last_comment_at, created_at DESC')

Update - in reply to your comment asking about the migration you'd need, the following should generate the migration for you: 更新-在回答您有关所需迁移的评论时,以下内容将为您生成迁移:

rails generate migration add_last_comment_at_to_posts last_comment_at:datetime

As others have noted, you can add an after_save call to your Comment model to update the last_comment_at field in your Post model. 正如其他人指出的那样,您可以在Comment模型中添加一个after_save调用,以更新Post模型中的last_comment_at字段。 I would use something like this: 我会用这样的东西:

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

First, you need to add another datetime column to your post. 首先,您需要在帖子中添加另一个datetime列。 Let's call it content_changed_at or something similar. 我们称它为content_changed_at或类似名称。 In a new post it has value of created_at . 在新帖子中,其值为created_at Then you update it every time a comment gets posted. 然后,每当有评论发布时,您就对其进行更新。 When you need to display posts, you just sort it by this column. 当您需要显示帖子时,只需按此列对其进行排序。

Here's untested code, but it should give you the idea. 这是未经测试的代码,但是它可以带给您想法。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM