组合2个对象和排序轨道5

时间:2016-11-19 18:27:17

标签: ruby-on-rails ruby object

我想显示一个混合评论和帖子的时间链接,所以我有这个对象

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

如果我这样做

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

我将收到第一篇文章,之后发表评论。但我想要一个时间表,我怎么能创造这个呢?

我需要将两个对象组合成一个有序列表,例如:

在帖子中:

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

在评论中:

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

如果我这样做 post.each ... comments.each ...

结果将是:

-post1
-post2
-comment1
-comment2

但我需要按日期排序才能获得

-post2
-comment1
-post1
-comment2

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

2 个答案:

答案 0 :(得分:2)

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

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

我的TimelineItem模型包含source_idsource_typetimeline_at字段。

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 }

答案 1 :(得分:0)

<强>溶液#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)

但联合查询仅在两个表中具有相同列名时才起作用。

解决方案#2 在视图中添加排序逻辑。

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

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

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

class Text < ActiveRecord::Base
end

class Post < Text 
end

class Comment < Text
end

查询将为Text.order(:date)

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