将mysql查询转换为rails查询
大家好,我在将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: 到目前为止,我可
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我试图在一个查询中更新所有用户的所有评论。我不想在结果上迭代,因为在大数据集中,它可能会遇到问题。因此,我关心的是一个没有迭代的单一查询。您至少应该使用
。查找每个,它将成批加载记录,而不是耗尽可用内存并导致崩溃。