RuntimeError:无法修改冻结的哈希rspec

时间:2019-02-05 19:15:06

标签: ruby-on-rails-4 rspec factory-bot

我有一个呼叫RiskMatrix模型,该模型将score存储为string 如果我使用FactoryBot构建对象,然后保存,则会得到:

RuntimeError:
  Can't modify frozen hash
     # /Users/mike/.rvm/gems/ruby-2.4.4/gems/activerecord-4.2.11/lib/active_record/attribute_set/builder.rb:45:in `[]='
# /Users/mike/.rvm/gems/ruby-2.4.4/gems/activerecord-4.2.11/lib/active_record/attribute_set.rb:39:in `write_from_user'
# /Users/mike/.rvm/gems/ruby-2.4.4/gems/activerecord-4.2.11/lib/active_record/attribute_methods/write.rb:74:in `write_attribute_with_type_cast'
# /Users/mike/.rvm/gems/ruby-2.4.4/gems/activerecord-4.2.11/lib/active_record/attribute_methods/write.rb:56:in `write_attribute'
# /Users/mike/.rvm/gems/ruby-2.4.4/gems/activerecord-4.2.11/lib/active_record/attribute_methods/dirty.rb:97:in `write_attribute'
# /Users/mike/.rvm/gems/ruby-2.4.4/gems/activerecord-4.2.11/lib/active_record/attribute_methods.rb:369:in `[]='
# /Users/mike/.rvm/gems/ruby-2.4.4/gems/activerecord-4.2.11/lib/active_record/autosave_association.rb:445:in `save_belongs_to_association'
# /Users/mike/.rvm/gems/ruby-2.4.4/gems/activerecord-4.2.11/lib/active_record/autosave_association.rb:201:in `block in add_autosave_association_callbacks'
# /Users/mike/.rvm/gems/ruby-2.4.4/gems/activerecord-4.2.11/lib/active_record/autosave_association.rb:157:in `instance_eval'
# /Users/mike/.rvm/gems/ruby-2.4.4/gems/activerecord-4.2.11/lib/active_record/autosave_association.rb:157:in `block in define_non_cyclic_method'
# /Users/mike/.rvm/gems/ruby-2.4.4/gems/activesupport-4.2.11/lib/active_support/callbacks.rb:432:in `block in make_lambda'
# /Users/mike/.rvm/gems/ruby-2.4.4/gems/activesupport-4.2.11/lib/active_support/callbacks.rb:164:in `block in halting'
# /Users/mike/.rvm/gems/ruby-2.4.4/gems/activesupport-4.2.11/lib/active_support/callbacks.rb:504:in `block in call'
# /Users/mike/.rvm/gems/ruby-2.4.4/gems/activesupport-4.2.11/lib/active_support/callbacks.rb:504:in `each'
# /Users/mike/.rvm/gems/ruby-2.4.4/gems/activesupport-4.2.11/lib/active_support/callbacks.rb:504:in `call'
# /Users/mike/.rvm/gems/ruby-2.4.4/gems/activesupport-4.2.11/lib/active_support/callbacks.rb:92:in `__run_callbacks__'
# /Users/mike/.rvm/gems/ruby-2.4.4/gems/activesupport-4.2.11/lib/active_support/callbacks.rb:778:in `_run_save_callbacks'
# /Users/mike/.rvm/gems/ruby-2.4.4/gems/activerecord-4.2.11/lib/active_record/callbacks.rb:302:in `create_or_update'
# /Users/mike/.rvm/gems/ruby-2.4.4/gems/activerecord-4.2.11/lib/active_record/persistence.rb:120:in `save'
# /Users/mike/.rvm/gems/ruby-2.4.4/gems/activerecord-4.2.11/lib/active_record/validations.rb:37:in `save'
# /Users/mike/.rvm/gems/ruby-2.4.4/gems/activerecord-4.2.11/lib/active_record/attribute_methods/dirty.rb:21:in `save'
# /Users/mike/.rvm/gems/ruby-2.4.4/gems/activerecord-4.2.11/lib/active_record/transactions.rb:286:in `block (2 levels) in save'
# /Users/mike/.rvm/gems/ruby-2.4.4/gems/activerecord-4.2.11/lib/active_record/transactions.rb:351:in `block in with_transaction_returning_status'
# /Users/mike/.rvm/gems/ruby-2.4.4/gems/activerecord-4.2.11/lib/active_record/connection_adapters/abstract/database_statements.rb:213:in `block in transaction'
# /Users/mike/.rvm/gems/ruby-2.4.4/gems/activerecord-4.2.11/lib/active_record/connection_adapters/abstract/transaction.rb:184:in `within_new_transaction'
# /Users/mike/.rvm/gems/ruby-2.4.4/gems/activerecord-4.2.11/lib/active_record/connection_adapters/abstract/database_statements.rb:213:in `transaction'
# /Users/mike/.rvm/gems/ruby-2.4.4/gems/activerecord-4.2.11/lib/active_record/transactions.rb:220:in `transaction'
# /Users/mike/.rvm/gems/ruby-2.4.4/gems/activerecord-4.2.11/lib/active_record/transactions.rb:348:in `with_transaction_returning_status'
# /Users/mike/.rvm/gems/ruby-2.4.4/gems/activerecord-4.2.11/lib/active_record/transactions.rb:286:in `block in save'
# /Users/mike/.rvm/gems/ruby-2.4.4/gems/activerecord-4.2.11/lib/active_record/transactions.rb:301:in `rollback_active_record_state!'
# /Users/mike/.rvm/gems/ruby-2.4.4/gems/activerecord-4.2.11/lib/active_record/transactions.rb:285:in `save'
# ./spec/models/risk_matrix_spec.rb:19:in `block (4 levels) in <top (required)>'
# /Users/mike/.rvm/gems/ruby-2.4.4/gems/vcr-2.9.3/lib/vcr/util/variable_args_block_caller.rb:9:in `call_block'
# /Users/mike/.rvm/gems/ruby-2.4.4/gems/vcr-2.9.3/lib/vcr.rb:182:in `use_cassette'
# ./spec/support/vcr.rb:19:in `block (2 levels) in <top (required)>'

我不知道为什么会这样。 请帮助

class RiskMatrix < ActiveRecord::Base
   belongs_to :user
   after_save :alert_admin, :save_suspicious_ip, if: proc {score.length >= ALERT_THRESHOLD}

    private
    def alert_admin
        [...]
    end

    def save_suspicious_ip
        [...]
    end
end

risk_matrix_spec.rb

 describe 'after_save' do
  context 'score.length > ALERT_THRESHOLD' do
    it 'should run alert_admin' do
      matrix = build(:risk_matrix, score: 'ABCD')
      expect(matrix).to receive(:alert_admin)
      matrix.save
    end 
  end
end

0 个答案:

没有答案