ROR 2版本出现NoMethodError:nil:NilClass未定义new_payment_model方法
解决ROR 2中的NoMethodError: undefined method `new_payment_model' for nil:NilClass
嘿,这个错误一看就知道问题出在哪了!咱们先拆解下根源:
你碰到的NoMethodError本质是当前的Authorization实例没有关联任何franchisee对象——也就是a.franchisee的值是nil,这时候你直接调用nil.new_payment_model,Ruby自然会报错说找不到这个方法。
来看你代码里的验证逻辑:
class Authorization < ActiveRecord::Base belongs_to :franchisee belongs_to :deleted_by, :class_name => 'User', :foreign_key => :deleted_by belongs_to :created_by, :class_name => 'User', :foreign_key => :created_by has_many :transactions validates_presence_of :notify_email validates_presence_of :activation_price, :expires_on validates_length_of :notify_email, :maximum => 255 validates_format_of :notify_email, :with => EMAIL_REGEX validates_numericality_of :activation_price, :greater_than => 0.0, :unless => Proc.new {|a| a.franchisee.new_payment_model} end
这里的Proc没有先检查franchisee是否存在,就直接调用它的方法,一旦franchisee为nil,就触发了错误。
两种解决方案,根据你的业务需求选:
方案1:强制Authorization必须关联franchisee
如果你的业务规则里,每个Authorization都必须属于一个franchisee,那直接加一个存在验证,从根源上避免franchisee为nil的情况:
class Authorization < ActiveRecord::Base belongs_to :franchisee belongs_to :deleted_by, :class_name => 'User', :foreign_key => :deleted_by belongs_to :created_by, :class_name => 'User', :foreign_key => :created_by has_many :transactions # 新增:确保franchisee存在 validates_presence_of :franchisee validates_presence_of :notify_email validates_presence_of :activation_price, :expires_on validates_length_of :notify_email, :maximum => 255 validates_format_of :notify_email, :with => EMAIL_REGEX validates_numericality_of :activation_price, :greater_than => 0.0, :unless => Proc.new {|a| a.franchisee.new_payment_model} end
方案2:允许Authorization没有franchisee
如果业务上允许Authorization不关联franchisee,那就要做安全判断——如果你的Ruby版本支持(Ruby 2.3+),可以用安全导航操作符&.;如果版本较低,就用条件判断:
# 简洁的安全导航写法(推荐) validates_numericality_of :activation_price, :greater_than => 0.0, :unless => Proc.new {|a| a.franchisee&.new_payment_model} # 兼容低版本Ruby的条件判断写法 validates_numericality_of :activation_price, :greater_than => 0.0, :unless => Proc.new {|a| a.franchisee && a.franchisee.new_payment_model}
这样当franchisee为nil时,表达式会返回nil/false,验证会正常执行,不会触发错误。
内容的提问来源于stack exchange,提问作者Dev
相关产品推荐
相关产品推荐

