Ruby on rails 使模型在Rails中不可删除

Ruby on rails 使模型在Rails中不可删除,ruby-on-rails,ruby,ruby-on-rails-4,model,ruby-on-rails-4.2,Ruby On Rails,Ruby,Ruby On Rails 4,Model,Ruby On Rails 4.2,怎样才能确保没有人能够通过控制台或试图调用model.destroy的控制器删除Rails中的模型记录?或者甚至尝试销毁与此不可删除模型的关系上设置了dependent::destroy的对象 这永远不会奏效: User.first.destroy 我从不希望某些模型在任何情况下丢失,当然,除了直接转到数据库或修改Ruby代码。我认为您应该分配一个引发错误的before\u destroy回调 class Model < ActiveRecord::Base before_destr

怎样才能确保没有人能够通过控制台或试图调用model.destroy的控制器删除Rails中的模型记录?或者甚至尝试销毁与此不可删除模型的关系上设置了dependent::destroy的对象

这永远不会奏效:

User.first.destroy
我从不希望某些模型在任何情况下丢失,当然,除了直接转到数据库或修改Ruby代码。

我认为您应该分配一个引发错误的before\u destroy回调

class Model < ActiveRecord::Base
  before_destroy :nope

  private

  def nope
    raise "nope!" if (id == 1)
  end
end
“摧毁前”也将拦截“摧毁”

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

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
在我看来,您应该分配一个引发错误的before_destroy回调

class Model < ActiveRecord::Base
  before_destroy :nope

  private

  def nope
    raise "nope!" if (id == 1)
  end
end
“摧毁前”也将拦截“摧毁”

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

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

在这个模型中,您总是可以覆盖destroy方法。@MarekLipka-这是正确的处理方法吗?没有其他方法可以销毁模型记录?您可能还需要注意删除:总有其他方法可以从数据库中销毁模型记录。您也可以覆盖public delete方法,但您仍然可以销毁记录,例如delete_all,或者您可以调用private destroy_row方法等。在数据库级别处理此问题可能更容易,例如,设置一个没有删除权限的用户,或者在MySQL中使用BEFORE DELETE触发器。在这个模型中,您总是可以覆盖DISTROY方法。@MarekLipka-这是正确的处理方法吗?没有其他方法可以销毁模型记录?您可能还需要注意删除:总有其他方法可以从数据库中销毁模型记录。您也可以覆盖public delete方法,但您仍然可以销毁记录,例如delete_all,或者您可以调用private destroy_row方法等。在数据库级别处理此问题可能更容易,例如,设置一个没有删除权限的用户,或者在MySQL中使用BEFORE DELETE触发器。如果已经覆盖destroy,则不必覆盖destroy\u all。如果您从销毁前返回falsy值,它也会阻止模型销毁。似乎销毁前抛出异常是一种方法。User.first.destroy只是一个例子。我不希望任何用户被销毁,不管他们是第一个还是最后一个。如果你已经覆盖了destroy,你不必覆盖destroy\u all。如果您从销毁前返回falsy值,它也会阻止模型销毁。似乎销毁前抛出异常是一种方法。User.first.destroy只是一个例子。我不希望任何用户被破坏,不管他们是第一个还是最后一个。