
Strange Immutable Error
Reported by Siegfried Levin | January 14th, 2011 @ 12:49 AM
In my application, there should be only one Loan record between
two people in a specific currency. (They can have other Loan record
in different currencies.) So I give it composite keys in class
definition.
class Loan
include DataMapper::Resource
belongs_to :loaner, Person, :key => true
belongs_to :loanee, Person, :key => true
property :currency, Enum[*CURRENCY_CODES], :key => true
property :amount, Decimal, :scale => 2, :default => 0
validates_with_block :if => :new? do
Loan.get(currency, loanee_id, loaner_id).nil?
end
validates_with_block do
loaner == loanee ? false : true
end
def reverse
self.loaner, self.loanee, self.amount = loanee, loaner, -amount
end
def self.count!(money_flow)
loan = get(money_flow.currency, money_flow.giver_id, money_flow.receiver_id)
loan.amount += money_flow.amount
end
before :save do
reverse if amount < 0
end
extend Forwardable
def_delegator :loaner, :local_id, :loaner_local_id
def_delegator :loanee, :local_id, :loanee_local_id
end
But when I get a specific record by keys, the record is
immutable.This is the test code for count! class method in Loan.
describe "#count!" do
subject { lambda { Loan.count!(money_flow) } }
context "when a loan exists from giver to receiver" do
let!(:loan) { Loan.gen }
let(:money_flow) { MoneyFlow.gen(:giver => loan.loaner, :receiver => loan.loanee, :currency => loan.currency) }
it { should_not change(Loan, :count) }
end
end
Attach the backtrace...
Failures:
1) Loan#count! when a loan exists from giver to receiver
Failure/Error: Loan.count!(money_flow)
DataMapper::ImmutableError:
Immutable resource cannot be modified
# /Users/siegfried/.rvm/gems/ruby-1.9.2-p136/gems/dm-core-1.0.2/lib/dm-core/resource/state/immutable.rb:16:in `set'
# /Users/siegfried/.rvm/gems/ruby-1.9.2-p136/gems/dm-core-1.0.2/lib/dm-core/model/property.rb:251:in `amount='
# ./lib/models.rb:49:in `count!'
# ./spec/models_spec.rb:64:in `block (4 levels) in <top (required)>'
# /Users/siegfried/.rvm/gems/ruby-1.9.2-p136/gems/rspec-expectations-2.4.0/lib/rspec/matchers/change.rb:17:in `call'
# /Users/siegfried/.rvm/gems/ruby-1.9.2-p136/gems/rspec-expectations-2.4.0/lib/rspec/matchers/change.rb:17:in `matches?'
# /Users/siegfried/.rvm/gems/ruby-1.9.2-p136/gems/rspec-expectations-2.4.0/lib/rspec/expectations/handler.rb:34:in `handle_matcher'
# /Users/siegfried/.rvm/gems/ruby-1.9.2-p136/gems/rspec-expectations-2.4.0/lib/rspec/expectations/extensions/kernel.rb:50:in `should_not'
# ./spec/models_spec.rb:63:in `block (3 levels) in <top (required)>'
# /Users/siegfried/.rvm/gems/ruby-1.9.2-p136/gems/rspec-core-2.4.0/lib/rspec/core/example.rb:49:in `instance_eval'
# /Users/siegfried/.rvm/gems/ruby-1.9.2-p136/gems/rspec-core-2.4.0/lib/rspec/core/example.rb:49:in `block (2 levels) in run'
# /Users/siegfried/.rvm/gems/ruby-1.9.2-p136/gems/rspec-core-2.4.0/lib/rspec/core/example.rb:98:in `with_around_hooks'
# /Users/siegfried/.rvm/gems/ruby-1.9.2-p136/gems/rspec-core-2.4.0/lib/rspec/core/example.rb:46:in `block in run'
# /Users/siegfried/.rvm/gems/ruby-1.9.2-p136/gems/rspec-core-2.4.0/lib/rspec/core/example.rb:91:in `block in with_pending_capture'
# /Users/siegfried/.rvm/gems/ruby-1.9.2-p136/gems/rspec-core-2.4.0/lib/rspec/core/example.rb:90:in `catch'
# /Users/siegfried/.rvm/gems/ruby-1.9.2-p136/gems/rspec-core-2.4.0/lib/rspec/core/example.rb:90:in `with_pending_capture'
# /Users/siegfried/.rvm/gems/ruby-1.9.2-p136/gems/rspec-core-2.4.0/lib/rspec/core/example.rb:45:in `run'
# /Users/siegfried/.rvm/gems/ruby-1.9.2-p136/gems/rspec-core-2.4.0/lib/rspec/core/example_group.rb:261:in `block in run_examples'
# /Users/siegfried/.rvm/gems/ruby-1.9.2-p136/gems/rspec-core-2.4.0/lib/rspec/core/example_group.rb:257:in `map'
# /Users/siegfried/.rvm/gems/ruby-1.9.2-p136/gems/rspec-core-2.4.0/lib/rspec/core/example_group.rb:257:in `run_examples'
# /Users/siegfried/.rvm/gems/ruby-1.9.2-p136/gems/rspec-core-2.4.0/lib/rspec/core/example_group.rb:231:in `run'
# /Users/siegfried/.rvm/gems/ruby-1.9.2-p136/gems/rspec-core-2.4.0/lib/rspec/core/example_group.rb:232:in `block in run'
# /Users/siegfried/.rvm/gems/ruby-1.9.2-p136/gems/rspec-core-2.4.0/lib/rspec/core/example_group.rb:232:in `map'
# /Users/siegfried/.rvm/gems/ruby-1.9.2-p136/gems/rspec-core-2.4.0/lib/rspec/core/example_group.rb:232:in `run'
# /Users/siegfried/.rvm/gems/ruby-1.9.2-p136/gems/rspec-core-2.4.0/lib/rspec/core/command_line.rb:27:in `block (2 levels) in run'
# /Users/siegfried/.rvm/gems/ruby-1.9.2-p136/gems/rspec-core-2.4.0/lib/rspec/core/command_line.rb:27:in `map'
# /Users/siegfried/.rvm/gems/ruby-1.9.2-p136/gems/rspec-core-2.4.0/lib/rspec/core/command_line.rb:27:in `block in run'
# /Users/siegfried/.rvm/gems/ruby-1.9.2-p136/gems/rspec-core-2.4.0/lib/rspec/core/reporter.rb:12:in `report'
# /Users/siegfried/.rvm/gems/ruby-1.9.2-p136/gems/rspec-core-2.4.0/lib/rspec/core/command_line.rb:24:in `run'
# /Users/siegfried/.rvm/gems/ruby-1.9.2-p136/gems/rspec-core-2.4.0/lib/rspec/core/runner.rb:55:in `run_in_process'
# /Users/siegfried/.rvm/gems/ruby-1.9.2-p136/gems/rspec-core-2.4.0/lib/rspec/core/runner.rb:46:in `run'
# /Users/siegfried/.rvm/gems/ruby-1.9.2-p136/gems/rspec-core-2.4.0/lib/rspec/core/runner.rb:10:in `block in autorun'
Comments and changes to this ticket
Please Sign in or create a free account to add a new ticket.
With your very own profile, you can contribute to projects, track your activity, watch tickets, receive and update tickets through your email and much more.
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »