Removing the key on currency only will lead to only one Loan record between two people, and they cannot have other Loan in different currency. So I remove all of them (keys), and add a id Serial property. With this validation, not ImmutableError recurs yet. Do you think I should submit a ticket for this?
On Jan 14, 2011, at 7:39 AM, RipTheJacker wrote: > Yes, the composite keys match your requirement, so you can leave them > for the belongs_to associations. And I'm starting to think this may > really be a bug. See if this works: > > remove the :key => true from :currency and add this: > validates_uniqueness_of :currency, :scope => [:loaner_id, :loanee_id] > > On Jan 13, 1:53 am, Zhi-Qiang Lei <[email protected]> wrote: >> Excuse me, a little more discussion please. In my past design, there should >> be ONLY ONE Loan record between two people in a specific currency. The >> composite keys match this requirement, don't they? But to make it immutable. >> >> On Jan 13, 2011, at 3:17 AM, RipTheJacker wrote: >> >> >> >>> Those won't make it immutable, but the key does need to be unique. So, >>> unless you can only have ONE Loan per Person you should probably >>> change those too. Rather than making them keys you probably mean to >>> have them as indexes, which I DataMapper does for you, and add an :id >>> Serial primary key to the model, the same as it is in your MoneyFlow >>> model. >> >>> On Jan 12, 12:28 am, Zhi-Qiang Lei <[email protected]> wrote: >>>> Hi, >> >>>> This model also has two more keys, they make a composite keys. This will >>>> also make it immutable? >> >>>>>>>> belongs_to :loaner, Person, :key => true >>>>>>>> belongs_to :loanee, Person, :key => true >> >>>> On Jan 12, 2011, at 3:15 AM, RipTheJacker wrote: >> >>>>> Ok. It's because of this: >> >>>>> property :currency, Enum[*CURRENCY_CODES], :key => true >> >>>>> You can't have :key => true on an Enum property since it is not >>>>> unique. >> >>>>> On Jan 10, 11:22 pm, Zhi-Qiang Lei <[email protected]> wrote: >>>>>> Hi, >> >>>>>> I still get the error with your spec code, here is 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/r >>>>>> esource/state/immutable.rb:16:in `set' >>>>>> # >>>>>> /Users/siegfried/.rvm/gems/ruby-1.9.2-p136/gems/dm-core-1.0.2/lib/dm-core/m >>>>>> odel/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/li >>>>>> b/rspec/matchers/change.rb:17:in `call' >>>>>> # >>>>>> /Users/siegfried/.rvm/gems/ruby-1.9.2-p136/gems/rspec-expectations-2.4.0/li >>>>>> b/rspec/matchers/change.rb:17:in `matches?' >>>>>> # >>>>>> /Users/siegfried/.rvm/gems/ruby-1.9.2-p136/gems/rspec-expectations-2.4.0/li >>>>>> b/rspec/expectations/handler.rb:34:in `handle_matcher' >>>>>> # >>>>>> /Users/siegfried/.rvm/gems/ruby-1.9.2-p136/gems/rspec-expectations-2.4.0/li >>>>>> b/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' >> >>>>>> On Jan 11, 2011, at 7:05 AM, RipTheJacker wrote: >> >>>>>>> You should probably just change that spec. The element that you want >>>>>>> to test is a proc (you hope) getting invoked inside of the subject >>>>>>> block, which is a weird pattern, and you don't need the #let blocks >>>>>>> really, since you only use those objects once. >> >>>>>>> Try: >> >>>>>>> describe "#count!" do >>>>>>> specify "when a loan exists from giver to receiver" do >>>>>>> loan = Loan.gen >>>>>>> money_flow = MoneyFlow.gen(:giver => loan.loaner, :receiver => >>>>>>> loan.loanee, :currency => loan.currency) >>>>>>> expect do >>>>>>> Loan.count!(money_flow) >>>>>>> end.to_not change(Loan, :count) >>>>>>> end >>>>>>> end >> >>>>>>> I'm assuming you are using rspec 2, though it will work in rspec 1.x >>>>>>> with a syntax change. If you still get that error, post the new >>>>>>> backtrace here. At the very least the spec and the backtrace will be >>>>>>> more meaningful this way, and may be easier to debug (I hope). >> >>>>>>> On Jan 10, 10:42 am, Zhi-Qiang Lei <[email protected]> wrote: >>>>>>>> Hi, >> >>>>>>>> I have some code as follow. >> >>>>>>>> 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 >> >>>>>>>> def self.count!(money_flow) >>>>>>>> loan = get(money_flow.currency, money_flow.giver_id, >>>>>>>> money_flow.receiver_id) >>>>>>>> loan.amount += money_flow.amount >>>>>>>> end >> >>>>>>>> # more code... >>>>>>>> end >> >>>>>>>> class MoneyFlow >>>>>>>> include DataMapper::Resource >>>>>>>> belongs_to :giver, Person >>>>>>>> belongs_to :receiver, Person >> >>>>>>>> property :id, Serial >>>>>>>> property :amount, Decimal, :scale => 2, :min => 0.01 >>>>>>>> property :currency, Enum[*CURRENCY_CODES], :default => :CNY >> >>>>>>>> # more code... >>>>>>>> end >> >>>>>>>> When I test the "count!" class method as follow: >> >>>>>>>> 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 >> >>>>>>>> It tells me I got a Immutable Error. I feel strange on that. They have >>>>>>>> keys, and I didn't destroy the record. Can you see why? Thanks. >> >>>>>>>> 1) Loan#count! when a loan exists from giver to receiver >>>>>>>> Failure/Error: subject { lambda { Loan.count!(money_flow) } } >>>>>>>> DataMapper::ImmutableError: >>>>>>>> Immutable resource cannot be modified >>>>>>>> # ./lib/models.rb:49:in `count!' >>>>>>>> # ./spec/models_spec.rb:59:in `block (4 levels) in <top >>>>>>>> (required)>' >>>>>>>> # ./spec/models_spec.rb:63:in `block (4 levels) in <top >>>>>>>> (required)>' >> >>>>>>>> On Jan 10, 2011, at 11:34 PM, Ted Han wrote: >> >>>>>>>>> Objects are immutable when they've been deleted or frozen for some >>>>>>>>> reason. Deleting a record from your data store will always result in >>>>>>>>> that record being frozen. >> >>>>>>>>> Is there a specific problem that you're having? >> >>>>>>>>> -T >> >>>>>>>>> On Mon, Jan 10, 2011 at 10:23 AM, Zhi-Qiang Lei >>>>>>>>> <[email protected]> wrote: >>>>>>>>> Dear All, >> >>>>>>>>> Could anyone answer me when a resource should be immutable? And why? >>>>>>>>> Thanks. >> >>>>>>>>> Best regards, >>>>>>>>> Zhi-Qiang Lei >>>>>>>>> [email protected] >> >>>>>>>>> -- >>>>>>>>> You received this message because you are subscribed to the Google >>>>>>>>> Groups "DataMapper" group. >>>>>>>>> To post to this group, send email to [email protected]. >>>>>>>>> To unsubscribe from this group, send email to >>>>>>>>> [email protected]. >>>>>>>>> For more options, visit this group >>>>>>>>> athttp://groups.google.com/group/datamapper?hl=en. >> >>>>>>>>> -- >>>>>>>>> You received this message because you are subscribed to the Google >>>>>>>>> Groups "DataMapper" group. >>>>>>>>> To post to this group, send email to [email protected]. >>>>>>>>> To unsubscribe from this group, send email to >>>>>>>>> [email protected]. >>>>>>>>> For more options, visit this group >>>>>>>>> athttp://groups.google.com/group/datamapper?hl=en. >> >>>>>>>> Best regards, >>>>>>>> Zhi-Qiang Lei >>>>>>>> [email protected] >> >>>>>>> -- >>>>>>> You received this >> >> ... >> >> read more ยป > > -- > You received this message because you are subscribed to the Google Groups > "DataMapper" group. > To post to this group, send email to [email protected]. > To unsubscribe from this group, send email to > [email protected]. > For more options, visit this group at > http://groups.google.com/group/datamapper?hl=en. > Best regards, Zhi-Qiang Lei [email protected] -- You received this message because you are subscribed to the Google Groups "DataMapper" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/datamapper?hl=en.
