我有三种模式:
用户:
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
进行软删除,并且我在所有三个表中都有deleted
列User, Post, Comment
用户销毁方法:
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
方法,我不知道如何有效地做到这一点。
我不想使用任何一种宝石。
请告诉我一种更好的方法来对这些关联进行软删除..
答案 0 :(得分:1)
你真的需要删除这些帖子吗?您可以通过在检索用户模型时包含用户模型来取代它们。当从父母那里很容易地推断出将所有后代标记为已删除时,确实没有必要。
用户:
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
答案 1 :(得分:1)
如果完全是关于效率(去除N + 1),我会做以下事情。我也是&#34;脂肪模型和瘦身控制者&#34;所以我会把你的逻辑从控制器转移到用户模型:
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不会触发更新实体的任何验证或回调。