更新父母的所有子女,以及该子女的子女

时间:2019-10-10 10:43:32

标签: sql ruby-on-rails ruby postgresql

我正在尝试尽可能高效地更新父母的孩子。由于表的架构是已知的,因此它不必是递归的。

表格:

  • 论坛上有很多帖子
  • 帖子有很多评论
  • 评论有很多回复

目标更新该论坛的帖子,以及他们的评论,依此类推。所有链接的记录都需要更新(所有表上的DateTime类型的delete_at字段)。

此外,Ruby不是必须的,它可以用SQL(Postgresql)编写。

我现在所拥有的:

group.posts.map(&:comments).flatten.map{ |c| c.touch }

仅更新注释。

有没有更好的方式来更新尽可能少的查询?

[{SQL] CTE递归在这里不可用?

SQL模式:

Groups:
ID Name Deleted_at
1 Stackoverflow null
2 Programming null

Posts:
ID Title Deleted_at Group_id
1 Stackoverflowqestion null 1
2 StupidQuestionOnStack null 1

Comments:
ID Body Deleted_at post_id
1 ThaIsStupid null 1

Replies:
ID Body Deleted_at comment_id
1 yep null 1

2 个答案:

答案 0 :(得分:0)

我相信您可以使用Rails关联和回调来解决此问题。 例如在您的小组模型中

class Group < ApplicationRecord
  has_many :posts
  has_many :comments, through: :posts # add this association

  after_update :update_comments # will be called after `Group` object updates successfully

  def update_comments
    comments.map(&:touch) # can apply required logic here
  end
end

类似地,您可以创建一个回调链(例如,也可以在posts模型中添加回调)来根据需要更新其他记录。

答案 1 :(得分:0)

最好使用以下关系,

class Group < ApplicationRecord

  has_many :comments, through: :posts

end

轨距<6.0

group.comments.map(&:touch)

# or with single SQL query
group.comments.update_all(updated_at: Time.now)

Rails 6.0

group.comments.touch_all

有关更多信息,您可以阅读此doc