rails模型不会在create上填充属性,失败的非null db test

时间:2016-12-21 08:18:35

标签: ruby-on-rails rails-activerecord

尝试为我的用户创建一个api_key。已设置为非空。

rails 4,而不是-null被触发,但我正在创建access_tokenbefore create,为什么? 如果在puts中我def generate_access_token我可以看到填充了access_token 它几乎就像它没有包含访问令牌(参见底部的db记录)作为save命令的一部分。

难倒!我肯定错过了一些愚蠢的东西吗?

  • 如果它在DB I中的非空值无法执行after_save
  • 我尝试过update_attribute而不是直接属性 - 这不会作为新对象工作

测试.log

      SQL (0.5ms)  INSERT INTO "api_keys" ("created_at", "updated_at") VALUES (?, ?)  [["created_at", "2016-12-21 08:09:07.304051"], ["updated_at", "2016-12-21 08:09:07.304051"]]

*缺少access_token * 为什么?

错误

    $ rspec spec/models/api_key_spec.rb 
    F

    Failures:

      1) ApiKey populates token
         Failure/Error: let!(:a) { FactoryGirl.create(:api_key) }

         ActiveRecord::StatementInvalid:
           SQLite3::ConstraintException: NOT NULL constraint failed: api_keys.user_id: INSERT INTO "api_keys" ("created_at", "updated_at") VALUES (?, ?)
           .....
         # --- Caused by: ---
         # SQLite3::ConstraintException:
         #   NOT NULL constraint failed: api_keys.user_id
         #   /Users/ben.forrest/.rvm/gems/ruby-2.2.5@baseapi/gems/sqlite3-1.3.12/lib/sqlite3/statement.rb:108:in `step'

    Finished in 0.11903 seconds (files took 3.32 seconds to load)
    1 example, 1 failure

    Failed examples:

    rspec ./spec/models/api_key_spec.rb:5 # ApiKey populates token

api_key_spec.rb

    require 'rails_helper'
    RSpec.describe ApiKey, type: :model do
    let!(:a) { FactoryGirl.create(:api_key) }
        it "populates token" do
           expect(a.access_token).to match /[A-Za-z0-9]{32}/
        end 
    end

api_key.rb

    class ApiKey < ActiveRecord::Base  
      attr_accessor :access_token, :expires_at, :user_id, :active, :application
      before_create :generate_access_token
      before_create :set_expiration
      belongs_to :user

      def expired?
        DateTime.now >= self.expires_at
      end

      private
      def generate_access_token
        begin
          self.access_token = SecureRandom.hex
        end while self.class.exists?(access_token: access_token)
        puts "**** access_token: #{access_token}****" # this shows it is created
      end

      def set_expiration
        self.expires_at = DateTime.now+30
      end
    end  

迁移

    class CreateApiKeys < ActiveRecord::Migration  
      def change
        create_table :api_keys do |t|
          t.string :access_token,      null: false
          t.integer :user_id,          null: false
          t.boolean :active,           null: false, default: true
          t.datetime :expires_at

          t.timestamps
        end

        add_index :api_keys, ["user_id"], name: "index_api_keys_on_user_id", unique: false
        add_index :api_keys, ["access_token"], name: "index_api_keys_on_access_token", unique: true
      end
    end 

1 个答案:

答案 0 :(得分:1)

[[NSBundle bundleForClass:[self class]] pathForResource:[filename stringByDeletingPathExtension] ofType:[filename pathExtension]] while self.class.exists?(access_token: access_token)变为假。请先尝试在access_token = nil之前分配令牌。

begin