【问题标题】:Unique undefined method error rails独特的未定义方法错误轨
【发布时间】:2014-05-26 18:19:16
【问题描述】:

我在 Rails 中有一个非常独特的“未定义方法错误”案例。我有一个具有“obligatedAmount”和“awardAmount”属性的任务订单模型。创建新任务订单时,我的业务规则之一是“obligatedAmount”不能大于“awardAmount”。所以确保这一点,我做了一个自定义验证:

validate :check_amount_obilgated
validates_presence_of :awardAmount
validates_presence_of :obligatedAmount


def check_amount_obilgated #cannot be greater than contract award amount
    if obligatedAmount > awardAmount
        errors.add(:obligatedAmount, "The Obligated Amount cannot be greater than the Award Amount")
    end
  end

这很好用。但是,如果我创建一个新的任务订单并将“obligatedAmount”或“awardAmount”留空,我 Rails 会将我带到错误页面,并显示错误 sn-p:

undefined method `>' for nil:NilClass'

def check_amount_obilgated #cannot be greater than contract award amount
    if obligatedAmount > awardAmount
        errors.add(:obligatedAmount, "The Obligated Amount cannot be greater than the Award Amount")
    end
  end

所以我想问题是,如果缺少一个或两个值,“>”运算符将无法工作。但是,我输入了 validates_presence_of :awardAmount 和 :obligatedAmount... 有什么办法可以让验证首先启动,或者有什么办法可以解决这个错误?请告诉我。谢谢!!

【问题讨论】:

标签: ruby-on-rails methods undefined


【解决方案1】:

使用to_i 将 nil 转换为零

def check_amount_obilgated #cannot be greater than contract award amount
    if obligatedAmount.to_i > awardAmount.to_i
        errors.add(:obligatedAmount, "The Obligated Amount cannot be greater than the Award Amount")
    end
end

【讨论】:

    【解决方案2】:

    所以解释很简单。 > 运算符是在 Fixnum 类上定义的。 NilClass 没有定义>,所以会抛出未定义的方法错误。如果将 nil 传递给有效调用,则会出现比较错误,因为 nil 不能隐式强制为 Fixnum。

    如果 nil 出现在右手或左手操作数中,快速检查 irb 会显示您可以预期的错误:

    2.1.2 :001 > 1 > nil
    ArgumentError: comparison of Fixnum with nil failed
        from (irb):1:in `>'
        from (irb):1
        from /Users/hungerandthirst/.rvm/rubies/ruby-2.1.2/bin/irb:11:in `<main>'
    2.1.2 :002 > nil > 1
    NoMethodError: undefined method `>' for nil:NilClass
        from (irb):2
        from /Users/hungerandthirst/.rvm/rubies/ruby-2.1.2/bin/irb:11:in `<main>'
    

    对两个操作数进行简单的强制转换 to_i 将导致值为零时为零,您将始终能够运行比较。

    2.1.2 :005 > nil.to_i
     => 0
    

    所以在你的代码中,做:

    obligatedAmount.to_i > awardAmount.to_i
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多