【问题标题】:Ruby on Rails prevent nil error when it is assumed record may not exist当假定记录可能不存在时,Ruby on Rails 防止出现 nil 错误
【发布时间】:2009-09-20 22:42:11
【问题描述】:

我正在构建一个简单的图书借阅应用程序。我需要做的一件事是确定一本书是否已签出。我通过 book_check_out 类设置了我的人员和书籍类之间的关联。我的目标是使用 book 的 checked_out 属性来确定当前是否已签出一本书。但是,在我目前的实现中,当一本书没有被签出并且我参考 book.checked_out.XXX 时,我收到错误“你没有预料到它有一个 nil 对象!”我的目标是在某些视图中将 book.checked_out 用于两个目的表明是的,该书已签出,而在其他视图中则显示当前签出给谁。

class Person < ActiveRecord::Base
  has_many :book_check_outs
  has_many :books, :through => :book_check_outs
end

class Book < ActiveRecord::Base

  has_many :book_check_outs
  has_many :people, :through => :book_check_outs

  def checked_out
    book_check_outs || false
  end
end

class BookCheckOut < ActiveRecord::Base
  belongs_to :book
  belongs_to :person
end

【问题讨论】:

    标签: ruby-on-rails null belongs-to has-and-belongs-to-many has-one


    【解决方案1】:

    当您得到一个布尔结果,可以是真或假(例如,一本书可以被检出或不被检出),您需要假设结果的默认值。在这种情况下,我们可以假设它是错误的(默认情况下不会签出该书)。

    在 book 模型中,删除您的 has_many :checked_out 行并创建一个具有相同名称的方法:

    def checked_out
      book_check_outs || false
    end
    

    应该返回 BookCheckOuts,或者如果没有与实例相关联,则返回 FALSE。它为您提供了一种快速、简单、万无一失的方法来检查关联并消除讨厌的 nil 对象错误。

    编辑您也可以只返回 TRUE 或 FALSE,而不通过检查 book_check_outs 是否为 nil 来返回最近的结帐。 Rails 提供了一个叫空白的方法?哪个都叫零?还是空的?

    def checked_out
      !book_check_outs.blank?
    end
    

    我爱鲁比 :)

    【讨论】:

    • 不幸的是,这会返回错误“未初始化的常量 Book::BookCheckOuts”。我喜欢这个想法,但我唯一担心的是,如果 BookCheckOuts 集合只是最近一次检出并且未检出,则返回 false 是完美的。
    • 我确实收到了“未初始化的常量 Book::BookCheckOuts”,直到我将两者都更改为 book_check_outs。我认为这与数据库命名约定有关。
    • 抱歉,深夜响应等等,脑子里一片混乱,忘记了你需要访问生成的访问器而不是类。
    【解决方案2】:

    我忘记了它是否真的重要,但为了清楚起见,您可能希望将 has_many 关系放在 has_many :through 关系之上。

    我也不确定你是否应该在 Book 类中声明它 has_many :BookCheckOuts 并且它 has_one :checked_out,因为 check_out 实际上是一个 BookCheckOut,你声明它具有上述许多。

    【讨论】:

    • 我同意 has_many 和 has_one 感觉有点尴尬。我正在寻找解决此问题的“正确”方式。我已经切换了 has_many 和 has_many。我也不确定这是否重要,但我同意你的建议让事情更清楚。
    • 好吧,我想我的问题是:您的图书馆中是否有同一本书的多个副本,因此可以借出不同的副本?如果 not 那么你只需要一个 has_one 关系。如果您确实有多个副本,那么您可能希望拥有像 PhysicalBook 模型这样的东西,它代表您拥有的每本实体书...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-24
    • 2021-09-19
    • 1970-01-01
    相关资源
    最近更新 更多