将mysql查询转换为rails查询

将mysql查询转换为rails查询,mysql,ruby-on-rails,Mysql,Ruby On Rails,大家好,我在将mysql查询转换为rails查询时遇到了一个问题。 我有这些模型- class User < ApplicationRecord has_many :comments, foreign_key: "commenter_id" end class Comment < ApplicationRecord belongs_to :commenter, class_name: "User" end 我试图使软删除评论,其评论者被软删除 更新1: 到目前为止,我可

大家好,我在将mysql查询转换为rails查询时遇到了一个问题。 我有这些模型-

class User < ApplicationRecord
   has_many :comments, foreign_key: "commenter_id"
end

class Comment < ApplicationRecord
  belongs_to :commenter, class_name: "User"
end
我试图使软删除评论,其评论者被软删除

更新1: 到目前为止,我可以用这个-

User.only_deleted.includes(:comments).find_each do |u|
  u.comments.update_all(deleted_at: u.deleted_at)
end
但我希望在单个查询上执行此操作,而不必迭代结果

更新2: 我使用的是acts_作为_偏执宝石,因此需要取消扫描用户,我的最终查询是:

User.unscoped{Comment.joins(:commenter).where.not(users: {deleted_at: nil}).update_all("comments.deleted_at = users.deleted_at") 

从你的评论来看,我认为这就是你想要的:

Comment.where.not(user_id: nil).each { |comment| comment.update_attributes(deleted_at: comment.user.deleted_at)
或者更具可读性:

Comment.all.each do |comment|
  next unless comment.user.present?
  comment.update_attributes(deleted_at: comment.user.deleted_at)
end

这应该适用于MySQL:

Comment
    .joins(:user)
    .where.not(users: { deleted_at: nil })
    .update_all("comments.deleted_at = users.deleted_at")
这在Postgres上不起作用,因为它缺少一个针对用户的FROM子句

一个性能较差但多克隆的选项是:

Comment
  .joins(:user)
  .where.not(users: { deleted_at: nil })
  .update_all("deleted_at = ( SELECT users.deleted_at FROM users WHERE comments.id = users.id )")

这可能仍然比在Ruby中迭代记录要好一个数量级,因为您消除了应用程序服务器和数据库之间的通信延迟。

下面的代码应该执行与已删除用户对应的查询数量,并且不在内存中加载用户和任何相关注释

deleted_users_data_arr = User.only_deleted.pluck(:id, :deleted_at)

deleted_users_data_arr.each do |arr|
  deleted_user_id = arr[0]
  user_deleted_at = arr[1]

  Comment.where(commenter_id: deleted_user_id).update_all(deleted_at: user_deleted_at)
end

当用户被软删除时,您似乎正在尝试软删除评论。然后我建议在行动中,软删除用户,也软删除评论<代码>@user.comments.update\u all(删除地址:@user.deleted\u at)或类似内容。请提供模型和关联的详细信息too@Maxence我试图在一个查询中更新所有用户的所有评论。我不想在结果上迭代,因为在大数据集中,它可能会遇到问题。因此,我关心的是一个没有迭代的单一查询。您至少应该使用
。查找每个
,它将成批加载记录,而不是耗尽可用内存并导致崩溃。