【问题标题】:Ruby on Rails before_destroy causing NameErrorRuby on Rails before_destroy 导致 NameError
【发布时间】:2009-09-25 19:11:03
【问题描述】:

我正在尝试在模型上实现 before_destroy。当我关注这个before_destroy example 时,我要么收到一个NameError,要么最终得到一些不符合before_destroy 的东西。我的语法有什么问题?

class Person < ActiveRecord::Base

  has_many :book_loans, :order => 'return_date desc'
  has_many :books, :through => :book_loans

  before_destroy
    errors.add_to_base "Cannot delete borrower with loans" unless
                                                           book_loans.count == 0
end

无法编译

  before_destroy
    errors.add_to_base "Cannot delete borrower with loans" unless
                                                           book_loans.count == 0

不起作用

def before_destroy
  errors.add_to_base "Cannot delete borrower with loans" unless
                                                         book_loans.count == 0
end

【问题讨论】:

    标签: ruby-on-rails activerecord


    【解决方案1】:

    您不能添加错误before_destroy,因为它们不会影响验证。您必须在验证发生之前添加错误,例如before_validation.

    还有一些额外的回调,before_validation_on_createbefore_validation_on_update。但是,没有on_destroy 版本,因为从未调用过savevalid?,因此在尝试销毁某些内容时添加验证错误将毫无意义。

    换句话说:您的before_destroy 运行,但它不会影响任何事情,因为在您销毁记录时不会检查验证错误。

    以下是实现基于特定条件阻止记录保存的一种方法。

    before_destroy :require_no_book_loans
    
    private
    
    def require_no_book_loans
      raise ActiveRecord::RecordInvalid unless book_loans.count == 0
    end
    

    您也可以创建自己的错误类并引发它。

    仅供参考:在您的语法错误示例中,您应该将一个块传递给before_destroy

    before_destroy {|r|
      r.errors.add_to_base "Foo" # ...
    }
    

    【讨论】:

    • 那么我该如何防止一个有贷款的人被毁掉呢?
    • Sweet 所以这会引发错误。考虑到只有在特殊情况下才应该发生异常,我最好还是阻止销毁链接在用户有贷款时出现?
    • 是的,这听起来很明智。人们仍然可以通过请求手动销毁它来伪造它,但是你提出了一个错误,所以它无论如何都不会被销毁。
    猜你喜欢
    • 2021-10-29
    • 2015-09-29
    • 2011-02-23
    • 1970-01-01
    • 1970-01-01
    • 2011-01-09
    • 1970-01-01
    • 2011-04-13
    • 1970-01-01
    相关资源
    最近更新 更多