#1475 new
Siegfried Levin

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.

New-ticket Create new ticket

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile »

Shared Ticket Bins

People watching this ticket

Pages