我有三个模特:
用户:
class User < ActiveRecord::Base
has_many :posts, :dependent => :destroy
scope :active, -> { where(deleted: false) }
end邮报:
class Post < ActiveRecord::Base
belongs_to :user
has_many :comments, :dependent => :destroy
scope :active, -> { where(deleted: false) }
end评论:
class Comment < ActiveRecord::Base
belongs_to :post
scope :active, -> { where(deleted: false) }
end现在,我正在对User进行软删除,在所有三个表(User, Post, Comment)中都有名为deleted的列。
用户破坏方法:
def destroy
@user = user.find(params[:id])
if @user.update_attributes(deleted: true)
@user.posts.each do |post|
post.comments.update_all(deleted: true)
end
@user.posts.update_all(deleted: true)
end
end上面的实现需要更多的时间,而不是。文章和评论的数量很高,这也造成了N+1查询问题。
和上面一样,我已经为destroy实现了Post方法,我不知道如何有效地实现它。
我不想用任何宝石。
请告诉我一种更好的方法来对这类联想进行软删除。
发布于 2016-07-06 12:50:59
你真的需要删除这些帖子吗?您可以通过在检索它们时包含用户模型来筛选它们。将所有后代标记为已删除并不是必要的,因为从父级可以很容易地推断出来。
用户:
class User < ActiveRecord::Base
has_many :posts, :dependent => :destroy
scope :active, -> { where(deleted: false) }
end员额:
class Post < ActiveRecord::Base
belongs_to :user
has_many :comments, :dependent => :destroy
scope :active, -> { joins(:user).merge(User.active) }
end发布于 2016-07-06 13:12:11
如果这一切都是关于效率(删除N+1),我会做以下工作。我也支持“胖模型和瘦控制器”,所以我会将您的逻辑从控制器转移到用户模型:
class User < ActiveRecord::Base
has_many :posts, dependent: :destroy
has_many :comments, through: :posts
scope :active, -> { where(deleted: false) }
after_save :delete_posts_and_comments, if: :delete_posts?
private
def delete_posts?
deleted_changed? && deleted
end
def delete_posts_and_comments
posts.update_all(deleted: true)
comments.update_all(deleted: true)
end
end当然,您也可以使用相同的模式来撤消删除。
注意!update_all不触发更新实体的任何验证或回调。
https://stackoverflow.com/questions/38224279
复制相似问题