Rails Active Record Query - 分类,基于'updated_at'值排序

时间:2016-05-16 18:31:46

标签: mysql ruby-on-rails ruby ajax will-paginate

在我的Rails网络应用程序(Rails 3.2.9Ruby 1.9.3)中,有一个专门针对每个用户的文章仪表板页面,其中列出了他/她创建的所有文章。有一些主要类别,其中应该列出文章。文章详细信息以表格结构显示。

Sl#     Name           Reference       Updated At

Category 1
1       Article 1      abc abc         05/16/2016 11:12AM
2       Article 2      pqr stu         05/14/2016 10:11PM
3       Article 3      abc abc         05/13/2016 05:05AM

Category 2
4       Article 4      abc abc         05/16/2016 11:00AM
5       Article 5      pqr stu         05/15/2016 06:41PM

Category 3
6       Article 6      abc abc         05/16/2016 10:12AM
7       Article 7      pqr stu         05/01/2016 09:52PM
8       Article 8      abc abc         05/12/2016 12:05PM

因此,该用户创建了8篇文章,比如说“Ramu”,它们分为3类。文章可以随时更新。第一条规则是

  

需要显示包含最新更新文章的类别   顶部等等

所以,在这里你可以看到Article 1的{​​{1}}已经更新,然后是第2类的第2类。所以,类别1,然后类别2等。

  

第二条规则是应对类别下的文章进行排序   基于DESC顺序的updated_at值。

Category 1

此查询无法按预期顺序获取结果,因为具有最新更新文章的类别可以包含与其他类别的文​​章相比具有较小@articles = @current_user.articles.order('updated_at DESC').paginate(page: params[:page], per_page: 10) 值的文章。但最新更新的文章以及第1类的其他文章将列在顶部,依此类推。

updated_at

上述内容也无法使用,因为它首先根据category_id进行排序。

有人可以帮助我获得优化的MySQL查询。谢谢。

1 个答案:

答案 0 :(得分:1)

class Category < ActiveRecord::Base
  has_many :articles
  #has_many :ordered_articles , -> {order(updated_at: :desc)}, class_name: 'Article', foreign_key: 'category_id'
  has_many :ordered_articles , order: "updated_at desc", class_name: 'Article', foreign_key: 'category_id'
end

class Article < ActiveRecord::Base
  belongs_to :category
end

这是您的问题的解决方案

@categories = Category.select("categories.id,categories.name  , max(articles.updated_at) as last_article").joins(:articles).group("categories.id").order("last_article desc").includes(:ordered_articles).where("articles.user_id = ?",current_user.id)

所有的魔力都在这里讨厌。

这将按您想要的顺序返回所有类别。 它将返回按文章updated_at列排序的所有类别。

其次,我在has_many课程中添加了一个新的category关联。 它的名字是ordered_articles。这就像正常的has_many :articles关联有序文章的好处。它将返回由articles排序的category的所有updated_at desc。如果需要,您可以在原始order关联上添加这些has_many功能。

现在categories实例变量中的所有@categories都可用。循环遍历它并通过调用articles来获取该类别中的所有ordered_articles。 I-E

@categories.each do |category|
 puts category.name
  category.ordered_articles.each do |article|
  puts article.title
  end
end

这就是你想要的输出。您可以根据需要获取其他属性。我假设您的Category有一个名为name的列,文章有一列title

您可以将其更改为实际列。

P.S:我们可以跳过新的has_many关联,可以使用articles子句在每个category对象上调用order_by e:g category.articles.order(updated_at: :desc)但这会导致N + 1查询困境。因此,eager load每个类别的相应文章我添加了一个新的关联,按照我们想要的顺序返回文章