【问题标题】:combine 2 objects and sort rails 5组合 2 个对象并排序导轨 5
【发布时间】:2017-04-03 10:45:33
【问题描述】:

我想显示一个混合 cmets 和 post 的时间链接,所以我有这个对象

@posts = Post::all()
@comments = Comment::all()

如果我这样做

@post.each ...
... end
@comments.each ...
... end

我将获得第一个帖子,然后是 cmets。但我想要一个时间线,我该如何创建?

我需要结合这两个对象来创建一个有序列表,例如:

在帖子中:

id | name | date
1 | post1 | 2015-01-01
2 | post2 | 2013-01-01

在 cmets 中:

id | name | date
1 | comment1 | 2014-01-01
2 | comment2 | 2016-01-01

如果我这样做 post.每个... cmets.each ...

结果将是:

-post1
-post2
-comment1
-comment2

但我需要按日期订购

-post2
-comment1
-post1
-comment2

谢谢,对不起我丑陋的英语。

【问题讨论】:

  • 什么是时间线,您希望我们如何帮助您创建它?
  • 我认为 OP 需要一个按日期/时间排序的列表。这就是所谓的时间线。
  • 请注意,Post::all() 应该是 Post.all,因为方法调用应该使用 . 进行,并且传统上会省略空参数列表。在像这样加载 Universe 时,我也会非常谨慎,因为您的帖子表可能包含数百万条记录,并且此代码会因内存不足而立即使您的应用程序崩溃。尽可能尝试使用分页。

标签: ruby-on-rails ruby object


【解决方案1】:

posts 和 cmets 是不同的模型(和不同的表),所以我们不能编写 SQL 来获取排序集合,分页等。

当我需要混合时间线时,我通常使用下一种方法。

我有带有source_idsource_typetimeline_at 字段的TimelineItem 模型。

class TimelineItem < ApplicationRecord
  belongs_to :source, polymorphic: true
end

然后我添加模型逻辑以在需要时创建timeline_item 实例:

has_many :timeline_items, as: :source
after_create :add_to_timeline

def add_to_timeline
  timeline_items.create timeline_at: created_at
end

然后搜索输出就这么简单

TimelineItem.includes(:source).order(:timeline_at).each { |t| pp t.source }

【讨论】:

  • 是的,专用的时间线模型是要走的路。
  • 然而,这段代码有 huuuuge N+1 查询问题:)
  • @SergioTulentsev 你不在这里,它至少在 Rails 4.2 中有效
  • 啊,确实,它已经被反向移植了,看来:stackoverflow.com/a/28025500/125816
  • 我现在看到了,漂亮的印刷品。
【解决方案2】:

解决方案#1 您可以使用 UNION 查询来实现这一点。

sql= 'SELECT id, name, date FROM posts UNION ALL SELECT id, name, date FROM comments ORDER BY date'
ActiveRecord::Base.connection.execute(sql)

但联合查询只有在两个表中的列名相同时才有效。

Solution#2 在您的视图中添加排序逻辑。

如果您只是在 html 页面上显示这些记录,那么让它们在没有任何特定顺序的情况下加载到页面上,即(先发帖,然后是 cmets)。编写 javascript 代码对页面加载后运行的 DOM 元素进行排序。

参考:Jquery - sort DIV's by innerHTML of children

解决方案#3 重构您的数据库架构并将帖子和 cmets 放在同一个数据库表中。然后您将能够在单个表上进行查询。 像这样的,

class Text < ActiveRecord::Base
end

class Post < Text 
end

class Comment < Text
end

查询将是Text.order(:date)

重构您的数据库架构无法解决这个问题。如果它对您的应用有意义,请执行此操作。

【讨论】:

  • OP 也可以有一个从帖子到评论的 has_many 关系。我认为这会有所帮助。
  • 是的,选项 #1 和 #3 并不可行。 #2 也不是!在这种情况下,分页是不可能的。
猜你喜欢
  • 2011-11-01
  • 2021-04-17
  • 2017-03-12
  • 1970-01-01
  • 2020-06-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多