2015-08-13 3 views
3

Rails 4.2Rails soft delete child record

У меня есть родительский класс, который принимает вложенные атрибуты для своих детей.

class Parent < ActiveRecord::Base 
    has_many :kids 
    accepts_nested_attributes_for :kids, allow_destroy: true 
end 

class Kid < ActiveRecord::Base 
    belongs_to :parent 

    def destroy 
    if some_count > 0 
     self.hidden = true 
    else 
     self.destroy 
    end 
    end 
end 

Я иногда хочу установить скрытый флаг на дочернем элементе, а не удалять его. Я делаю это через accepts_nested_attributes_for. Мне нужно, чтобы это решение было настроено на стороне сервера, я не могу заставить пользователей решить, следует ли уничтожать или скрывать.

Но не разрушающие повышения ActiveRecord::RecordNotDestroyed - Failed to destroy the record:

Что правильный способ сделать это?

+0

из документа «Поднято« ActiveRecord :: Persistence # destroy! », Когда вызов destroy будет возвращать false». (источник: http://api.rubyonrails.org/classes/ActiveRecord/RecordNotDestroyed.html) => вы, вероятно, назвали '.destroy!' в записи, и этот метод возвращает false, что вызывает ошибку – MrYoshiji

ответ

1

Ошибка вызывается из-за того, что вы попали в бесконечный цикл (вы вызываете метод destroy в методе destroy). Вместо этого используйте super. Также вам необходимо сохранить скрытое изменение столбца в базе данных. В этом случае она должна быть безопасной в использовании update_column (без проверки и никаких обратных вызовов не срабатывают никакие другие столбцы не будут сохранены в базе данных)

class Kid < ActiveRecord::Base 
    belongs_to :parent 

    def destroy 
    if some_count > 0 
     update_column(:hidden, true) 
    else 
     super 
    end 
    end 
end 

Чтобы ответить на другой вопрос, который вы должны объяснить, что some_count есть. :)

+0

Я не думаю использование 'update_column' является хорошей идеей здесь, потому что, как вы сказали, оно пропускает validationd и обратные вызовы, которые могут быть очень важными. IMO, в этом случае следует использовать регулярные 'update_attributes (hidden: true)' – MrYoshiji

+0

@MrYoshiji. Проблема с 'update_attributes' заключается в том, что она также сохранит все другие несохраненные атрибуты (поскольку она буквально вызывает сохранение внутри), что может и не быть предназначенный для «уничтожения» объекта. Мне действительно не хватает метода в rails, который обновляет один столбец, который запускает все обратные вызовы, однако я согласен с тем, что 'update_attributes' может быть немного безопаснее здесь. – BroiSatse