在Rails中使模型不可删除

时间:2015-03-18 09:59:29

标签: ruby-on-rails ruby ruby-on-rails-4 model ruby-on-rails-4.2

确保没有人可以通过控制台或尝试调用model.destroy的某个控制器删除Rails中的模型记录的正确方法是什么?或者甚至通过尝试销毁dependent: :destroy设置与此不可删除模型的关系的对象。

这应该永远不会起作用:

User.first.destroy

我绝不希望某些模型在任何情况下都会丢失(当然,除了直接进入数据库或更改Ruby代码之外)。

1 个答案:

答案 0 :(得分:4)

IMO你应该分配一个引发错误的before_destroy回调。

class Model < ActiveRecord::Base
  before_destroy :nope

  private

  def nope
    raise "nope!" if (id == 1)
  end
end

如果提出错误是不可接受的(如果它停止其他操作),您必须定义自己的destroy

class Model < ActiveRecord::Base
  def destroy
    super if should_destroy?
  end

  def should_destroy?
    id != 1
  end
end

before_destroy也会拦截destroy_all

但以下内容将有助于更明确地拦截destroy_all

class Model < ActiveRecord::Base
  class ActiveRecord_Relation
    def destroy_all
      where(id: 1).exists? ? raise("nope!") : super
    end
  end
end

Model.where(id: 1).destroy_all #=> nope! (nothing gets destroyed)
Model.where(id: [1, 2]).destroy_all #=> nope! (nothing gets destroyed)
Model.where(id: 2).destroy_all #=> destruction!!! carnage! HAVOC!

无错误的实施:

class Model < ActiveRecord::Base
  class ActiveRecord_Relation
    def destroy_all
      err_id = 1
      return super unless where(id: err_id).exists?

      ids = pluck(:id) - [err_id]
      where(id: ids).destroy_all
    end
  end
end