【问题标题】:Why nil:NilClass error when trying to access this self.attribute within model.rb?为什么在尝试访问 model.rb 中的 self.attribute 时出现 nil:NilClass 错误?
【发布时间】:2017-06-20 13:35:06
【问题描述】:

我正在尝试为 Employee 模型上的 date_of_birth attr 编写自己的验证,但我看不出我哪里出错了,我确信这真的很愚蠢而且就在我的眼皮底下。代码如下,我的错误信息是;

 NoMethodError:
    undefined method `<' for nil:NilClass

员工.rb

  class Employee < ApplicationRecord
  belongs_to :quote

    validates_presence_of :first_name, :last_name, :email, :gender, :date_of_birth, :salary
    validates :first_name, length: { minimum: 2, message: "minimum of 2 chars" }
    validates :last_name, length: { minimum: 2, message: "minimum of 2 chars" }
    validates_email_format_of :email, :message => 'incorrect email format'
    validate :older_than_16

    enum gender: [ :m, :f ]

    private

    def older_than_16
        self.date_of_birth < Time.now-16.years
    end

end

schema.rb

   ActiveRecord::Schema.define(version: 20170620125346) do

  # These are extensions that must be enabled in order to support this database
  enable_extension "plpgsql"

  create_table "employees", force: :cascade do |t|
    t.string   "first_name"
    t.string   "last_name"
    t.string   "email"
    t.string   "initial"
    t.integer  "gender"
    t.date     "date_of_birth"
    t.integer  "salary"
    t.integer  "quote_id"
    t.datetime "created_at",    null: false
    t.datetime "updated_at",    null: false
    t.index ["quote_id"], name: "index_employees_on_quote_id", using: :btree
  end

employee_spec.rb

RSpec.describe Employee, type: :model do
    describe 'validations' do   

        it { should validate_presence_of(:date_of_birth) }
        it { should_not allow_value(Date.today-15.years).for(:date_of_birth) }
        # it { should allow_value(Date.today-17.years).for(:date_of_birth) }
    end
end

【问题讨论】:

    标签: ruby-on-rails scope


    【解决方案1】:

    即使在第一次测试中也会调用您的自定义方法匹配器,但 self.date_of_birth 实际上是 nil,所以您会看到此错误。
    在比较之前,您必须检查 date_of_birth 是否不是 nil
    如果您认为您的模型无效,您还必须 add a new entryerrors 集合。
    (同时检查你的情况,我用&gt;而不是&lt;让你的测试通过)

      def older_than_16
          return if self.date_of_birth.nil?
          if self.date_of_birth > Time.now-16.years
              errors.add(:date_of_birth, "Should be at least 16 years old")
          end
      end
    

    【讨论】:

    • 感谢@Aschen,现在可以完美运行了。但我不明白self.date_of_birth 是怎么做到的?存在是否经过验证并通过了测试?怎么是零?谢谢你在这里帮助我??
    • 我不知道 should-matcher 在内部是如何工作的,但我认为 it { should validate_presence_of(:date_of_birth) } 尝试通过传递 nil 值来检查存在验证,除了模型将为 model.valid? 返回 false
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-22
    • 1970-01-01
    • 2016-04-19
    • 2018-07-17
    • 1970-01-01
    • 1970-01-01
    • 2014-08-27
    相关资源
    最近更新 更多