我有一个呼叫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