2016-07-06 2 views
1

У меня есть три модели:Soft удалить с ассоциациями

Пользователь:

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

Вам действительно нужно удалить сообщения? Вместо этого вы можете использовать их, включая модель пользователя, когда вы их извлекаете. Маркировка всех потомков как удаленных действительно не требуется. – Matt

+0

Лучшим способом было бы использовать камень для этого: Паранойя (https://github.com/rubysherpas/paranoia) или ActsAsParanoid (https://github.com/ActsAsParanoid/acts_as_paranoid). –

+2

@gen Плакат утверждает, что он не хочет использовать драгоценный камень. – Matt

ответ

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

Если это все об эффективности (удаление 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 не вызывает никаких проверок или обратных вызовов для обновленных объектов.

+0

Спасибо за ваш ответ .. –

Смежные вопросы