开发者

Ruby method returns nil, problem with self reference

I have defined a method called ccy which takes in a number num, determines the currency (an attribute of the parent Record model) and returns the number multiplied by a conversion factor. Self, in this case, refers to a Setting, which has a number of attributes of its own and belongs to Record. The method is defined in the Setting model below:

开发者_高级运维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

This doesn't work, however, because after doing some tests I've discovered that self.record.currency is nil. So, when I try to do something like self.ccy(100) in a rails application, for example, I get the following error:

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.*

or this, if I'm doing using some sort of operator on the nil element:

TypeError: nil can't be coerced into Fixnum

I've looked around online for a bit and I can't seem to figure out exactly how to fix this. Help appreciated!


Maybe you have a scope problem? In

def ccy(num)
  self ...

The self there is referring to an instance of Setting (@setting).

It also seems that this method should be in your Record model. Also, you might consider using a hash for your conversion:

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


In addition to @monocle's excellent refactoring suggestion:

You might want to make sure that when you're saving the Record, there's a default currency value set.

Something like:

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

You might also have a/n (potentially implicit) :include_blank => true in your currency selector such that you're getting these empty values stored in the db.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜