I have three models:
User:
class User < ActiveRecord::Base
has_many :posts, :dependent => :destroy
scope :active, -> { where(deleted: false) }
end
Post:
class Post < ActiveRecord::Base
belongs_to :user
has_many :comments, :dependent => :destroy
scope :active, -> { where(deleted: false) }
end
Comment:
class Comment < ActiveRecord::Base
belongs_to :post
scope :active, -> { where(deleted: false) }
end
Now, I am doing soft delete for User
and I have column named deleted
in all three tables(User, Post, Comment
)
User destroy method:
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
The above implementation takes more time when no. of posts and comments are high and it also creates N+1 query problem..
Same as above I have implemented destroy
method for Post
, I don't know how to do it efficiently..
I don't want to use any kind of gem.
Please tell me a better way to do soft deletion for these kind of associations..
Do you really need to delete the posts? You could scope them out instead by including the user model when you retrieve them. Marking all descendants as deleted really isn't necessary when it can so easily be inferred from the parent.
User:
class User < ActiveRecord::Base
has_many :posts, :dependent => :destroy
scope :active, -> { where(deleted: false) }
end
Post:
class Post < ActiveRecord::Base
belongs_to :user
has_many :comments, :dependent => :destroy
scope :active, -> { joins(:user).merge(User.active) }
end