2013-09-11 3 views
0

Я пытаюсь создать простую систему мягкого удаления, добавив обратный вызов before_destroy, который устанавливает удаленный флаг, а затем возвращает false (чтобы предотвратить реальное уничтожение).Rails 4: self.update не работает внутри модели

class Project < ActiveRecord::Base 

    belongs_to :user 

    before_destroy :soft_delete 

    def soft_delete 
     self.update(is_deleted: 1) 
     false 
    end 

end 

Это делает не результата в записи получать обновления. Я не знаю, почему. Я вижу [1m[36m (0.4ms)[0m [1mROLLBACK[0m в моих журналах, но я не уверен, что это релевантно или нет.

ответ

1

Look here

Если before_ * обратный вызов возвращает ложь, все последующие обратные вызовы и соответствующего действия отменяются. Если обратный вызов after_ * возвращает false, все последующие обратные вызовы отменены. Обратные вызовы обычно выполняются в порядке, в котором они определены, за исключением обратных вызовов, определенных как методов на модели, которые называются последними.

+0

Так что моя стратегия не будет работать, потому что возврат 'false' отменяет обновление, которое устанавливает флаг. Это правильно? – emersonthis

+0

Да, это не продолжится. Думаю, вы должны переместить свою логику на свой контроллер. Или, может быть, поиск, если есть хорошая вещь, чтобы переопределить метод уничтожения модели. –

1

Я думаю self.update_columns(is_deleted: true) может работать ...

0

Я хотел бы предложить переопределение метода уничтожения непосредственно в контроллере. Как всегда, старайтесь следовать лучшей практике рельсов «Живого модельного тощего контроллера». Я бы сделал большую часть логики в модели, а затем просто вызовите его из контроллера, как это:

В модели:

def soft_delete! 
    update_attribute(:is_deleted, 1) 
    #remove any other attributes you want here (ie. if there are tasks associated with projects and such they should also be cascade "soft deleted here" 
end 

В контроллере:

def destroy 
    @project = Project.find(params[:id]) 
    @project.soft_delete! 
    redirect_to projects_path 
end 

Что-то вроде этого будет работать. Кроме того, вы можете:

  • Сделать soft_delete возвращать логическое значение, чтобы вы могли включить его контроллер и перенаправлять в другие места
  • Soft удалить другие связанные атрибуты в других моделях (где я добавил комментарий)
+0

По сути, я не думаю, что использование before_destroy - лучший способ добиться того, чего вы хотите :). – derekyau

0

Try self.update_attributes(is_deleted: 1)

работал для меня на Rails 4.2.4

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