Ruby方法返回nil,自引用的问题

时间:2011-06-07 21:30:14

标签: ruby-on-rails ruby null typeerror self-reference

我已经定义了一个名为ccy的方法,它接收一个数字num,确定货币(父记录模型的属性)并返回数字乘以转换因子。在这种情况下,Self指的是一个Setting,它有许多属性,属于Record。该方法在下面的设置模型中定义:

class Setting < ActiveRecord::Base
  belongs_to :record

  def ccy(num)
    self.record.currency == "USD" ? ( num * 1 ) :
    self.record.currency == "GBP" ? ( num * 0.616181 ) :
    self.record.currency == "EUR" ? ( num * 0.70618 ) :
    self.record.currency == "CAD" ? ( num * 0.97415 ) : nil
  end
end

然而,这不起作用,因为在做了一些测试之后我发现self.record.currency是零。因此,当我尝试在rails应用程序中执行self.ccy(100)之类的操作时,我收到以下错误:

You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.*

或者,如果我在nil元素上使用某种运算符:

TypeError: nil can't be coerced into Fixnum

我在网上看了一下,我似乎无法弄清楚如何解决这个问题。帮助赞赏!

2 个答案:

答案 0 :(得分:4)

也许你有范围问题?在

def ccy(num)
  self ...

自我指的是设置(@setting)的实例。

此方法似乎也应该在您的Record模型中。此外,您可以考虑使用哈希值进行转换:

class Setting < ActiveRecord::Base
  belongs_to :record
  delegate :convert_currecy, :to => :record
end

class Record < ActiveRecord::Base

 CURRENCY_CONVERSION_FACTOR =
  {
    "USD" => 1,
    "GBP" => 0.616181
  }

  def convert_currency(num)
    CURRENCY_CONVERSION_FACTOR[currency] * num
  end

答案 1 :(得分:1)

除了@ monocle的优秀重构建议:

您可能需要确保在保存记录时,设置了默认货币值。

类似的东西:

  validates_presence_of :currency
  before_save :default_currency
  def default_currency
     self.currency = "GBP" unless self.currency.present? #Woo Anglophilia!
  end

您的货币选择器中可能还有一个/ n(可能隐式):include_blank => true,这样您就可以将这些空值存储在数据库中。