The Depot Application

The Depot Application

21 Action Controller: Routing and URLs 19 ActiveRecord: Relationships Between Tables

20 ActiveRecord: Object Life Cycle

irb e1/ar/encrypt.rb
>> $: << File.dirname(__FILE__)
=> ["/home/rubys/git/awdwr/work-191-239/migration/app/controllers/", "/home/rubys/git/awdwr/work-191-239/migration/app", "/home/rubys/git/awdwr/work-191-239/migration/app/models", "/home/rubys/git/awdwr/work-191-239/migration/app/controllers", "/home/rubys/git/awdwr/work-191-239/migration/app/helpers", "/home/rubys/git/awdwr/work-191-239/migration/lib", "/home/rubys/git/awdwr/work-191-239/migration/vendor", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/railties/lib/../builtin/rails_info/", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/railties", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/railties/lib", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/activesupport/lib", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/actionpack/lib", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/activerecord/lib", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/actionmailer/lib", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/activeresource/lib", "/home/rubys/git/gorp/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/memcache-client-1.8.3/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/memcache-client-1.8.3/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/i18n-0.4.0.beta1/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/mime-types-1.16/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/rack-mount-0.6.3/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/text-format-1.0.0/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/rack-test-0.5.3/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/abstract-1.0.0/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/rdoc-2.5.8/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/rdoc-2.5.8/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/text-hyphen-1.0.0/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/text-hyphen-1.0.0/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/net-scp-1.0.2/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/bundler-1.0.0.rc.6/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/bundler-1.0.0.rc.6/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/thor-0.13.6/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/thor-0.13.6/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/highline-1.5.2/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/rack-1.1.0/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/rack-1.1.0/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/treetop-1.4.5/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/treetop-1.4.5/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/capistrano-2.5.18/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/capistrano-2.5.18/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/test-unit-2.0.7/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/test-unit-2.0.7/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/tzinfo-0.3.20/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/net-ssh-gateway-1.0.1/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/sqlite3-ruby-1.2.5/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/sqlite3-ruby-1.2.5/ext", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/sqlite3-ruby-1.2.5/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/arel-0.3.3/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/builder-2.1.2/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/htmlentities-4.2.1/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/net-ssh-2.0.22/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/polyglot-0.3.1/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/will_paginate-3.0.pre/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/net-sftp-2.0.4/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/erubis-2.6.5/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/erubis-2.6.5/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/mail-2.2.0/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378@global/gems/rake-0.8.7/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378@global/gems/rake-0.8.7/lib", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/site_ruby/1.9.1", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/site_ruby/1.9.1/i686-linux", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/site_ruby", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/vendor_ruby/1.9.1", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/vendor_ruby/1.9.1/i686-linux", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/vendor_ruby", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/1.9.1", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/1.9.1/i686-linux", ".", "/home/rubys/git/awdwr/data/code/e1/ar"]
>> require "connect"
=> true
 
>> require "rubygems"
=> []
>> require "active_record"
=> []
 
>> ActiveRecord::Schema.define do
 
?>   create_table :orders, :force => true do |t|
?>     t.integer :user_id
>>     t.string  :name
>>     t.string  :address
>>     t.string  :email
>>   end
 
>>   create_table :users, :force => :true do |t|
?>     t.string :name
>>   end
>> end
-- create_table(:orders, {:force=>true})
   -> 2.5335s
-- create_table(:users, {:force=>:true})
   -> 24.1385s
=> nil
 
 
?> class ActiveRecord::Base
>>   def self.encrypt(*attr_names)
>>     encrypter = Encrypter.new(attr_names)
 
>>     before_save encrypter
>>     after_save  encrypter
>>     after_find  encrypter
 
>>     define_method(:after_find) { }
>>   end
>> end
=> nil
 
?> class Encrypter
 
>>   # We're passed a list of attributes that should
?>   # be stored encrypted in the database
?>   def initialize(attrs_to_manage)
>>     @attrs_to_manage = attrs_to_manage
>>   end
 
>>   # Before saving or updating, encrypt the fields using the NSA and
?>   # DHS approved Shift Cipher
?>   def before_save(model)
>>     @attrs_to_manage.each do |field|
?>       model[field].tr!("a-z", "b-za")
>>     end
>>   end
 
>>   # After saving, decrypt them back
?>   def after_save(model)
>>     @attrs_to_manage.each do |field|
?>       model[field].tr!("b-za", "a-z")
>>     end
>>   end
 
>>   # Do the same after finding an existing record
?>   alias_method :after_find, :after_save
>> end
=> Encrypter
 
?> class Order < ActiveRecord::Base
>>   encrypt(:name, :email)
>> end
=> #<Proc:0x85867a0@/home/rubys/git/awdwr/data/code/e1/ar/encrypt.rb:33 (lambda)>
 
?> o = Order.new
=> #<Order id: nil, user_id: nil, name: nil, address: nil, email: nil>
>> o.name = "Dave Thomas"
=> "Dave Thomas"
>> o.address = "123 The Street"
=> "123 The Street"
>> o.email   = "dave@example.com"
=> "dave@example.com"
>> o.save
=> true
>> puts o.name
Dave Thomas
=> nil
 
>> o = Order.find(o.id)
=> #<Order id: 1, user_id: nil, name: "Dave Thomas", address: "123 The Street", email: "dave@example.com">
>> puts o.name
Dave Thomas
=> nil
>> >> => nil
sqlite3> select * from orders
     id = 1
user_id = 
   name = Dbwf Tipnbt
address = 123 The Street
  email = ebwf@fybnqmf.dpn
irb e1/ar/observer.rb
>> $: << File.dirname(__FILE__)
=> ["/home/rubys/git/awdwr/work-191-239/migration/app/controllers/", "/home/rubys/git/awdwr/work-191-239/migration/app", "/home/rubys/git/awdwr/work-191-239/migration/app/models", "/home/rubys/git/awdwr/work-191-239/migration/app/controllers", "/home/rubys/git/awdwr/work-191-239/migration/app/helpers", "/home/rubys/git/awdwr/work-191-239/migration/lib", "/home/rubys/git/awdwr/work-191-239/migration/vendor", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/railties/lib/../builtin/rails_info/", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/railties", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/railties/lib", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/activesupport/lib", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/actionpack/lib", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/activerecord/lib", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/actionmailer/lib", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/activeresource/lib", "/home/rubys/git/gorp/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/memcache-client-1.8.3/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/memcache-client-1.8.3/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/i18n-0.4.0.beta1/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/mime-types-1.16/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/rack-mount-0.6.3/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/text-format-1.0.0/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/rack-test-0.5.3/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/abstract-1.0.0/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/rdoc-2.5.8/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/rdoc-2.5.8/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/text-hyphen-1.0.0/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/text-hyphen-1.0.0/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/net-scp-1.0.2/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/bundler-1.0.0.rc.6/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/bundler-1.0.0.rc.6/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/thor-0.13.6/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/thor-0.13.6/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/highline-1.5.2/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/rack-1.1.0/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/rack-1.1.0/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/treetop-1.4.5/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/treetop-1.4.5/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/capistrano-2.5.18/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/capistrano-2.5.18/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/test-unit-2.0.7/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/test-unit-2.0.7/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/tzinfo-0.3.20/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/net-ssh-gateway-1.0.1/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/sqlite3-ruby-1.2.5/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/sqlite3-ruby-1.2.5/ext", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/sqlite3-ruby-1.2.5/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/arel-0.3.3/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/builder-2.1.2/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/htmlentities-4.2.1/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/net-ssh-2.0.22/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/polyglot-0.3.1/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/will_paginate-3.0.pre/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/net-sftp-2.0.4/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/erubis-2.6.5/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/erubis-2.6.5/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/mail-2.2.0/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378@global/gems/rake-0.8.7/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378@global/gems/rake-0.8.7/lib", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/site_ruby/1.9.1", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/site_ruby/1.9.1/i686-linux", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/site_ruby", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/vendor_ruby/1.9.1", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/vendor_ruby/1.9.1/i686-linux", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/vendor_ruby", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/1.9.1", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/1.9.1/i686-linux", ".", "/home/rubys/git/awdwr/data/code/e1/ar"]
 
>> require "rubygems"
=> false
>> require "active_record"
=> true
 
>> require 'connect'
=> []
 
>> ActiveRecord::Base.logger = Logger.new(STDERR)
=> #<Logger:0x9aa7334 @progname=nil, @level=0, @default_formatter=#<Logger::Formatter:0x9aa7318 @datetime_format=nil>, @formatter=nil, @logdev=#<Logger::LogDevice:0x9aa72c4 @shift_size=nil, @shift_age=nil, @filename=nil, @dev=#<IO:<STDERR>>, @mutex=#<Logger::LogDevice::LogDeviceMutex:0x9aa72a8 @mon_owner=nil, @mon_count=0, @mon_mutex=#<Mutex:0x9aa71c8>>>>
 
>> ActiveRecord::Schema.define do 
?>   create_table :payments, :force => true do |t|
?>   end
>> end
-- create_table(:payments, {:force=>true})
  SQL (0.3ms)   select sqlite_version(*)
  SQL (1.6ms)    SELECT name
 FROM sqlite_master
 WHERE type = 'table' AND NOT name = 'sqlite_sequence'

    
   -> 7.8955s
=> nil
 
>> class Order < ActiveRecord::Base
>> end
=> nil
 
>> class Payment < ActiveRecord::Base
>> end
=> nil
 
>> class Refund < ActiveRecord::Base
>> end
=> nil
 
  SQL (7745.0ms)   CREATE TABLE "payments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL) 
?> class OrderObserver < ActiveRecord::Observer
>>   def after_save(an_order)
>>     an_order.logger.info("Order #{an_order.id} created")
>>   end
>> end
=> nil
 
>> OrderObserver.instance
=> #<OrderObserver:0x8ad4730>
 
?> class AuditObserver < ActiveRecord::Observer
 
>>   observe Order, Payment, Refund
 
>>   def after_save(model)
>>     model.logger.info("[Audit] #{model.class.name} #{model.id} created")
>>   end
>> end
=> nil
 
>> AuditObserver.instance
=> #<AuditObserver:0x88474d8>
 
 
>> o = Order.create
  Order Create (0.7ms)   INSERT INTO "orders" ("user_id", "name", "address", "email") VALUES(NULL, NULL, NULL, NULL)
Order 2 created
[Audit] Order 2 created
  Payment Create (0.5ms)   INSERT INTO payments VALUES(NULL)
[Audit] Payment 1 created
=> #<Order id: 2, user_id: nil, name: nil, address: nil, email: nil>
>> p = Payment.create
=> #<Payment id: 1>
 
?> >> 
irb e1/ar/attributes.rb
>> $: << File.dirname(__FILE__)
=> ["/home/rubys/git/awdwr/work-191-239/migration/app/controllers/", "/home/rubys/git/awdwr/work-191-239/migration/app", "/home/rubys/git/awdwr/work-191-239/migration/app/models", "/home/rubys/git/awdwr/work-191-239/migration/app/controllers", "/home/rubys/git/awdwr/work-191-239/migration/app/helpers", "/home/rubys/git/awdwr/work-191-239/migration/lib", "/home/rubys/git/awdwr/work-191-239/migration/vendor", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/railties/lib/../builtin/rails_info/", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/railties", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/railties/lib", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/activesupport/lib", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/actionpack/lib", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/activerecord/lib", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/actionmailer/lib", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/activeresource/lib", "/home/rubys/git/gorp/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/memcache-client-1.8.3/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/memcache-client-1.8.3/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/i18n-0.4.0.beta1/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/mime-types-1.16/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/rack-mount-0.6.3/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/text-format-1.0.0/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/rack-test-0.5.3/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/abstract-1.0.0/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/rdoc-2.5.8/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/rdoc-2.5.8/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/text-hyphen-1.0.0/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/text-hyphen-1.0.0/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/net-scp-1.0.2/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/bundler-1.0.0.rc.6/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/bundler-1.0.0.rc.6/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/thor-0.13.6/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/thor-0.13.6/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/highline-1.5.2/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/rack-1.1.0/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/rack-1.1.0/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/treetop-1.4.5/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/treetop-1.4.5/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/capistrano-2.5.18/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/capistrano-2.5.18/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/test-unit-2.0.7/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/test-unit-2.0.7/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/tzinfo-0.3.20/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/net-ssh-gateway-1.0.1/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/sqlite3-ruby-1.2.5/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/sqlite3-ruby-1.2.5/ext", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/sqlite3-ruby-1.2.5/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/arel-0.3.3/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/builder-2.1.2/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/htmlentities-4.2.1/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/net-ssh-2.0.22/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/polyglot-0.3.1/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/will_paginate-3.0.pre/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/net-sftp-2.0.4/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/erubis-2.6.5/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/erubis-2.6.5/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/mail-2.2.0/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378@global/gems/rake-0.8.7/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378@global/gems/rake-0.8.7/lib", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/site_ruby/1.9.1", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/site_ruby/1.9.1/i686-linux", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/site_ruby", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/vendor_ruby/1.9.1", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/vendor_ruby/1.9.1/i686-linux", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/vendor_ruby", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/1.9.1", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/1.9.1/i686-linux", ".", "/home/rubys/git/awdwr/data/code/e1/ar"]
>> require "connect"
=> true
>> require "logger"
=> []
>> require "pp"
=> ["PP"]
 
>> #ActiveRecord::Base.logger = Logger.new(STDERR)
 
?> require "rubygems"
=> []
>> require "active_record"
=> []
 
>> class LineItem < ActiveRecord::Base
>> end
=> nil
 
>> LineItem.delete_all
=> 1
 
>> LineItem.create(:quantity => 1, :product_id => 27, :order_id => 13, :unit_price => 29.95)
=> #<LineItem id: 3, product_id: 27, order_id: 13, quantity: 1, unit_price: #<BigDecimal:8e5bacc,'0.2995E2',8(8)>>
>> LineItem.create(:quantity => 2, :unit_price => 29.95)
=> #<LineItem id: 4, product_id: nil, order_id: nil, quantity: 2, unit_price: #<BigDecimal:8df919c,'0.2995E2',8(8)>>
>> LineItem.create(:quantity => 1, :unit_price => 44.95)
=> #<LineItem id: 5, product_id: nil, order_id: nil, quantity: 1, unit_price: #<BigDecimal:8c78f80,'0.4495E2',8(8)>>
 
>> result = LineItem.find(:first)
=> #<LineItem id: 3, product_id: 27, order_id: 13, quantity: 1, unit_price: #<BigDecimal:8bf0a04,'0.2995E2',8(8)>>
>> p result.quantity
1
=> 1
>> p result.unit_price
#<BigDecimal:8ba6a08,'0.2995E2',8(8)>
=> #<BigDecimal:8ba6a08,'0.2995E2',8(8)>
 
>> result = LineItem.find_by_sql("select quantity, quantity*unit_price " +
?>                               "from line_items")
=> [#<LineItem quantity: 1>, #<LineItem quantity: 2>, #<LineItem quantity: 1>]
>> pp result[0].attributes
{"quantity"=>1, "quantity*unit_price"=>"29.95"}
=> nil
 
>> result = LineItem.find_by_sql("select quantity, 
                                      quantity*unit_price as total_price " +
?>                               "from line_items")
=> [#<LineItem quantity: 1>, #<LineItem quantity: 2>, #<LineItem quantity: 1>]
>> pp result[0].attributes
{"quantity"=>1, "total_price"=>"29.95"}
=> nil
 
>> p result[0].total_price
"29.95"
=> "29.95"
>> sales_tax = 0.07
=> 0.07
>> p result[0].total_price * sales_tax
""
=> ""
 
>> class LineItem < ActiveRecord::Base
>>   def total_price
>>     Float(read_attribute("total_price"))
>>   end
 
>>   CUBITS_TO_INCHES = 2.54
 
>>   def quantity
>>     read_attribute("quantity") * CUBITS_TO_INCHES
>>   end
 
>>   def quantity=(inches)
>>     write_attribute("quantity", Float(inches) / CUBITS_TO_INCHES)
>>   end
>> end
=> nil
 
>> p result[0].quantity
2.54
=> 2.54
 
>> result[0].quantity = 500
=> 500
>> p result[0].save
true
=> true
 
?> >> 
sqlite3> select id, quantity*unit_price from line_items
                 id = 3
quantity*unit_price = 29.95
 
                 id = 4
quantity*unit_price = 59.9
 
                 id = 5
quantity*unit_price = 44.95
irb e1/ar/transactions.rb 1
>> $: << File.dirname(__FILE__)
=> ["/home/rubys/git/awdwr/work-191-239/migration/app/controllers/", "/home/rubys/git/awdwr/work-191-239/migration/app", "/home/rubys/git/awdwr/work-191-239/migration/app/models", "/home/rubys/git/awdwr/work-191-239/migration/app/controllers", "/home/rubys/git/awdwr/work-191-239/migration/app/helpers", "/home/rubys/git/awdwr/work-191-239/migration/lib", "/home/rubys/git/awdwr/work-191-239/migration/vendor", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/railties/lib/../builtin/rails_info/", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/railties", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/railties/lib", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/activesupport/lib", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/actionpack/lib", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/activerecord/lib", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/actionmailer/lib", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/activeresource/lib", "/home/rubys/git/gorp/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/memcache-client-1.8.3/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/memcache-client-1.8.3/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/i18n-0.4.0.beta1/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/mime-types-1.16/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/rack-mount-0.6.3/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/text-format-1.0.0/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/rack-test-0.5.3/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/abstract-1.0.0/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/rdoc-2.5.8/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/rdoc-2.5.8/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/text-hyphen-1.0.0/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/text-hyphen-1.0.0/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/net-scp-1.0.2/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/bundler-1.0.0.rc.6/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/bundler-1.0.0.rc.6/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/thor-0.13.6/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/thor-0.13.6/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/highline-1.5.2/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/rack-1.1.0/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/rack-1.1.0/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/treetop-1.4.5/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/treetop-1.4.5/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/capistrano-2.5.18/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/capistrano-2.5.18/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/test-unit-2.0.7/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/test-unit-2.0.7/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/tzinfo-0.3.20/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/net-ssh-gateway-1.0.1/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/sqlite3-ruby-1.2.5/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/sqlite3-ruby-1.2.5/ext", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/sqlite3-ruby-1.2.5/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/arel-0.3.3/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/builder-2.1.2/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/htmlentities-4.2.1/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/net-ssh-2.0.22/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/polyglot-0.3.1/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/will_paginate-3.0.pre/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/net-sftp-2.0.4/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/erubis-2.6.5/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/erubis-2.6.5/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/mail-2.2.0/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378@global/gems/rake-0.8.7/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378@global/gems/rake-0.8.7/lib", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/site_ruby/1.9.1", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/site_ruby/1.9.1/i686-linux", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/site_ruby", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/vendor_ruby/1.9.1", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/vendor_ruby/1.9.1/i686-linux", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/vendor_ruby", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/1.9.1", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/1.9.1/i686-linux", ".", "/home/rubys/git/awdwr/data/code/e1/ar"]
>> require "connect"
=> true
>> require "logger"
=> []
 
>> #ActiveRecord::Base.logger = Logger.new(STDERR)
 
?> require "rubygems"
=> []
>> require "active_record"
=> []
 
 
>> ActiveRecord::Schema.define do 
?>   create_table :accounts, :force => true do |t|
?>     t.string  :number
>>     t.decimal :balance, :precision => 10, :scale => 2, :default => 0
>>   end
>> end
-- create_table(:accounts, {:force=>true})
   -> 10.6713s
=> nil
 
 
?> class Account < ActiveRecord::Base
>>   validate :price_must_be_at_least_a_cent
 
>>   def self.transfer(from, to, amount)
>>     transaction(from, to) do
?>       from.withdraw(amount)
>>       to.deposit(amount)
>>     end
>>   end
 
?>   def withdraw(amount)
>>     adjust_balance_and_save(-amount)
>>   end
 
>>   def deposit(amount)
>>     adjust_balance_and_save(amount)
>>   end
 
>>   private
 
>>   def adjust_balance_and_save(amount)
>>     self.balance += amount
>>     save!
>>   end
 
>>   def price_must_be_at_least_a_cent
>>     errors.add(:balance, "is negative") if balance < 0
>>   end
>> end
=> nil
 
?>   def adjust_balance_and_save(amount)
>>     self.balance += amount
>>   end
=> nil
 
?> peter = Account.create(:balance => 100, :number => "12345")
=> #<Account id: 1, number: "12345", balance: #<BigDecimal:851dc54,'0.1E3',4(8)>>
>> paul  = Account.create(:balance => 200, :number => "54321")
=> #<Account id: 2, number: "54321", balance: #<BigDecimal:83cbac0,'0.2E3',4(8)>>
 
>> case ARGV[0] || "1"
 
>> when "1"
>>   Account.transaction do
?>     paul.deposit(10)
>>     peter.withdraw(10)
>>   end
 
>> when "2"
>>   Account.transaction do
?>     paul.deposit(350)
>>     peter.withdraw(350)
>>   end
 
>> when "3"
>>   begin
?>     Account.transaction do
?>       paul.deposit(350)
>>       peter.withdraw(350)
>>     end
>>   rescue
>>     puts "Transfer aborted"
>>   end
 
>>   puts "Paul has #{paul.balance}"
>>   puts "Peter has #{peter.balance}"
 
>> when "4"
>>   begin
?>     Account.transaction(peter, paul) do
?>       paul.deposit(350)
>>       peter.withdraw(350)
>>     end
>>   rescue
>>     puts "Transfer aborted"
>>   end
 
>>   puts "Paul has #{paul.balance}"
>>   puts "Peter has #{peter.balance}"
 
>> when "5"
>>   Account.transfer(peter, paul, 350) rescue  puts "Transfer aborted"
 
>>   puts "Paul has #{paul.balance}"
>>   puts "Peter has #{peter.balance}"
 
>> end
=> true
 
 
 
>> >> => nil
sqlite3> select * from accounts
     id = 1
 number = 12345
balance = 90
 
     id = 2
 number = 54321
balance = 210
irb e1/ar/transactions.rb 2
>> $: << File.dirname(__FILE__)
=> ["/home/rubys/git/awdwr/work-191-239/migration/app/controllers/", "/home/rubys/git/awdwr/work-191-239/migration/app", "/home/rubys/git/awdwr/work-191-239/migration/app/models", "/home/rubys/git/awdwr/work-191-239/migration/app/controllers", "/home/rubys/git/awdwr/work-191-239/migration/app/helpers", "/home/rubys/git/awdwr/work-191-239/migration/lib", "/home/rubys/git/awdwr/work-191-239/migration/vendor", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/railties/lib/../builtin/rails_info/", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/railties", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/railties/lib", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/activesupport/lib", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/actionpack/lib", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/activerecord/lib", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/actionmailer/lib", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/activeresource/lib", "/home/rubys/git/gorp/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/memcache-client-1.8.3/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/memcache-client-1.8.3/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/i18n-0.4.0.beta1/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/mime-types-1.16/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/rack-mount-0.6.3/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/text-format-1.0.0/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/rack-test-0.5.3/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/abstract-1.0.0/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/rdoc-2.5.8/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/rdoc-2.5.8/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/text-hyphen-1.0.0/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/text-hyphen-1.0.0/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/net-scp-1.0.2/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/bundler-1.0.0.rc.6/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/bundler-1.0.0.rc.6/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/thor-0.13.6/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/thor-0.13.6/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/highline-1.5.2/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/rack-1.1.0/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/rack-1.1.0/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/treetop-1.4.5/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/treetop-1.4.5/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/capistrano-2.5.18/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/capistrano-2.5.18/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/test-unit-2.0.7/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/test-unit-2.0.7/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/tzinfo-0.3.20/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/net-ssh-gateway-1.0.1/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/sqlite3-ruby-1.2.5/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/sqlite3-ruby-1.2.5/ext", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/sqlite3-ruby-1.2.5/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/arel-0.3.3/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/builder-2.1.2/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/htmlentities-4.2.1/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/net-ssh-2.0.22/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/polyglot-0.3.1/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/will_paginate-3.0.pre/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/net-sftp-2.0.4/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/erubis-2.6.5/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/erubis-2.6.5/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/mail-2.2.0/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378@global/gems/rake-0.8.7/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378@global/gems/rake-0.8.7/lib", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/site_ruby/1.9.1", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/site_ruby/1.9.1/i686-linux", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/site_ruby", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/vendor_ruby/1.9.1", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/vendor_ruby/1.9.1/i686-linux", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/vendor_ruby", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/1.9.1", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/1.9.1/i686-linux", ".", "/home/rubys/git/awdwr/data/code/e1/ar"]
>> require "connect"
=> true
>> require "logger"
=> []
 
>> #ActiveRecord::Base.logger = Logger.new(STDERR)
 
?> require "rubygems"
=> []
>> require "active_record"
=> []
 
 
>> ActiveRecord::Schema.define do 
?>   create_table :accounts, :force => true do |t|
?>     t.string  :number
>>     t.decimal :balance, :precision => 10, :scale => 2, :default => 0
>>   end
>> end
-- create_table(:accounts, {:force=>true})
   -> 20.2971s
=> nil
 
 
?> class Account < ActiveRecord::Base
>>   validate :price_must_be_at_least_a_cent
 
>>   def self.transfer(from, to, amount)
>>     transaction(from, to) do
?>       from.withdraw(amount)
>>       to.deposit(amount)
>>     end
>>   end
 
?>   def withdraw(amount)
>>     adjust_balance_and_save(-amount)
>>   end
 
>>   def deposit(amount)
>>     adjust_balance_and_save(amount)
>>   end
 
>>   private
 
>>   def adjust_balance_and_save(amount)
>>     self.balance += amount
>>     save!
>>   end
 
>>   def price_must_be_at_least_a_cent
>>     errors.add(:balance, "is negative") if balance < 0
>>   end
>> end
=> nil
 
?>   def adjust_balance_and_save(amount)
>>     self.balance += amount
>>   end
=> nil
 
?> peter = Account.create(:balance => 100, :number => "12345")
=> #<Account id: 1, number: "12345", balance: #<BigDecimal:848a3e8,'0.1E3',4(8)>>
>> paul  = Account.create(:balance => 200, :number => "54321")
=> #<Account id: 2, number: "54321", balance: #<BigDecimal:83cb190,'0.2E3',4(8)>>
 
>> case ARGV[0] || "1"
 
>> when "1"
>>   Account.transaction do
?>     paul.deposit(10)
>>     peter.withdraw(10)
>>   end
 
>> when "2"
>>   Account.transaction do
?>     paul.deposit(350)
>>     peter.withdraw(350)
>>   end
 
>> when "3"
>>   begin
?>     Account.transaction do
?>       paul.deposit(350)
>>       peter.withdraw(350)
>>     end
>>   rescue
>>     puts "Transfer aborted"
>>   end
 
>>   puts "Paul has #{paul.balance}"
>>   puts "Peter has #{peter.balance}"
 
>> when "4"
>>   begin
?>     Account.transaction(peter, paul) do
?>       paul.deposit(350)
>>       peter.withdraw(350)
>>     end
>>   rescue
>>     puts "Transfer aborted"
>>   end
 
>>   puts "Paul has #{paul.balance}"
>>   puts "Peter has #{peter.balance}"
 
>> when "5"
>>   Account.transfer(peter, paul, 350) rescue  puts "Transfer aborted"
 
>>   puts "Paul has #{paul.balance}"
>>   puts "Peter has #{peter.balance}"
 
>> end
ActiveRecord::RecordInvalid: Validation failed: Balance is negative
	from /home/rubys/git/awdwr/work-191-239/migration/vendor/rails/activerecord/lib/active_record/validations.rb:1102:in `save_with_validation!'
	from /home/rubys/git/awdwr/work-191-239/migration/vendor/rails/activerecord/lib/active_record/dirty.rb:87:in `save_with_dirty!'
	from /home/rubys/git/awdwr/work-191-239/migration/vendor/rails/activerecord/lib/active_record/transactions.rb:200:in `block (2 levels) in save_with_transactions!'
	from /home/rubys/git/awdwr/work-191-239/migration/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb:136:in `transaction'
	from /home/rubys/git/awdwr/work-191-239/migration/vendor/rails/activerecord/lib/active_record/transactions.rb:182:in `transaction'
	from /home/rubys/git/awdwr/work-191-239/migration/vendor/rails/activerecord/lib/active_record/transactions.rb:200:in `block in save_with_transactions!'
	from /home/rubys/git/awdwr/work-191-239/migration/vendor/rails/activerecord/lib/active_record/transactions.rb:208:in `rollback_active_record_state!'
	from /home/rubys/git/awdwr/work-191-239/migration/vendor/rails/activerecord/lib/active_record/transactions.rb:200:in `save_with_transactions!'
	from /home/rubys/git/awdwr/data/code/e1/ar/transactions.rb:48:in `adjust_balance_and_save'
	from /home/rubys/git/awdwr/data/code/e1/ar/transactions.rb:37:in `withdraw'
	from /home/rubys/git/awdwr/data/code/e1/ar/transactions.rb:84:in `block in irb_binding'
	from /home/rubys/git/awdwr/work-191-239/migration/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb:136:in `transaction'
	from /home/rubys/git/awdwr/work-191-239/migration/vendor/rails/activerecord/lib/active_record/transactions.rb:182:in `transaction'
	from /home/rubys/git/awdwr/data/code/e1/ar/transactions.rb:82
	from /home/rubys/.rvm/rubies/ruby-1.9.1-p378/bin/irb:17:in `<main>'
 
 
 
>> >> => nil
sqlite3> select * from accounts
     id = 1
 number = 12345
balance = 100
 
     id = 2
 number = 54321
balance = 200
irb e1/ar/transactions.rb 3
>> $: << File.dirname(__FILE__)
=> ["/home/rubys/git/awdwr/work-191-239/migration/app/controllers/", "/home/rubys/git/awdwr/work-191-239/migration/app", "/home/rubys/git/awdwr/work-191-239/migration/app/models", "/home/rubys/git/awdwr/work-191-239/migration/app/controllers", "/home/rubys/git/awdwr/work-191-239/migration/app/helpers", "/home/rubys/git/awdwr/work-191-239/migration/lib", "/home/rubys/git/awdwr/work-191-239/migration/vendor", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/railties/lib/../builtin/rails_info/", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/railties", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/railties/lib", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/activesupport/lib", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/actionpack/lib", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/activerecord/lib", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/actionmailer/lib", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/activeresource/lib", "/home/rubys/git/gorp/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/memcache-client-1.8.3/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/memcache-client-1.8.3/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/i18n-0.4.0.beta1/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/mime-types-1.16/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/rack-mount-0.6.3/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/text-format-1.0.0/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/rack-test-0.5.3/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/abstract-1.0.0/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/rdoc-2.5.8/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/rdoc-2.5.8/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/text-hyphen-1.0.0/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/text-hyphen-1.0.0/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/net-scp-1.0.2/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/bundler-1.0.0.rc.6/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/bundler-1.0.0.rc.6/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/thor-0.13.6/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/thor-0.13.6/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/highline-1.5.2/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/rack-1.1.0/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/rack-1.1.0/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/treetop-1.4.5/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/treetop-1.4.5/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/capistrano-2.5.18/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/capistrano-2.5.18/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/test-unit-2.0.7/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/test-unit-2.0.7/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/tzinfo-0.3.20/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/net-ssh-gateway-1.0.1/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/sqlite3-ruby-1.2.5/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/sqlite3-ruby-1.2.5/ext", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/sqlite3-ruby-1.2.5/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/arel-0.3.3/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/builder-2.1.2/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/htmlentities-4.2.1/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/net-ssh-2.0.22/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/polyglot-0.3.1/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/will_paginate-3.0.pre/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/net-sftp-2.0.4/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/erubis-2.6.5/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/erubis-2.6.5/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/mail-2.2.0/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378@global/gems/rake-0.8.7/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378@global/gems/rake-0.8.7/lib", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/site_ruby/1.9.1", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/site_ruby/1.9.1/i686-linux", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/site_ruby", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/vendor_ruby/1.9.1", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/vendor_ruby/1.9.1/i686-linux", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/vendor_ruby", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/1.9.1", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/1.9.1/i686-linux", ".", "/home/rubys/git/awdwr/data/code/e1/ar"]
>> require "connect"
=> true
>> require "logger"
=> []
 
>> #ActiveRecord::Base.logger = Logger.new(STDERR)
 
?> require "rubygems"
=> []
>> require "active_record"
=> []
 
 
>> ActiveRecord::Schema.define do 
?>   create_table :accounts, :force => true do |t|
?>     t.string  :number
>>     t.decimal :balance, :precision => 10, :scale => 2, :default => 0
>>   end
>> end
-- create_table(:accounts, {:force=>true})
   -> 16.7178s
=> nil
 
 
?> class Account < ActiveRecord::Base
>>   validate :price_must_be_at_least_a_cent
 
>>   def self.transfer(from, to, amount)
>>     transaction(from, to) do
?>       from.withdraw(amount)
>>       to.deposit(amount)
>>     end
>>   end
 
?>   def withdraw(amount)
>>     adjust_balance_and_save(-amount)
>>   end
 
>>   def deposit(amount)
>>     adjust_balance_and_save(amount)
>>   end
 
>>   private
 
>>   def adjust_balance_and_save(amount)
>>     self.balance += amount
>>     save!
>>   end
 
>>   def price_must_be_at_least_a_cent
>>     errors.add(:balance, "is negative") if balance < 0
>>   end
>> end
=> nil
 
?>   def adjust_balance_and_save(amount)
>>     self.balance += amount
>>   end
=> nil
 
?> peter = Account.create(:balance => 100, :number => "12345")
=> #<Account id: 1, number: "12345", balance: #<BigDecimal:83c984c,'0.1E3',4(8)>>
>> paul  = Account.create(:balance => 200, :number => "54321")
=> #<Account id: 2, number: "54321", balance: #<BigDecimal:836706c,'0.2E3',4(8)>>
 
>> case ARGV[0] || "1"
 
>> when "1"
>>   Account.transaction do
?>     paul.deposit(10)
>>     peter.withdraw(10)
>>   end
 
>> when "2"
>>   Account.transaction do
?>     paul.deposit(350)
>>     peter.withdraw(350)
>>   end
 
>> when "3"
>>   begin
?>     Account.transaction do
?>       paul.deposit(350)
>>       peter.withdraw(350)
>>     end
>>   rescue
>>     puts "Transfer aborted"
>>   end
 
>>   puts "Paul has #{paul.balance}"
>>   puts "Peter has #{peter.balance}"
 
>> when "4"
>>   begin
?>     Account.transaction(peter, paul) do
?>       paul.deposit(350)
>>       peter.withdraw(350)
>>     end
>>   rescue
>>     puts "Transfer aborted"
>>   end
 
>>   puts "Paul has #{paul.balance}"
>>   puts "Peter has #{peter.balance}"
 
>> when "5"
>>   Account.transfer(peter, paul, 350) rescue  puts "Transfer aborted"
 
>>   puts "Paul has #{paul.balance}"
>>   puts "Peter has #{peter.balance}"
 
>> end
Transfer aborted
Paul has 550.0
Peter has -250.0
=> nil
 
 
 
>> >> => nil
irb e1/ar/transactions.rb 4
>> $: << File.dirname(__FILE__)
=> ["/home/rubys/git/awdwr/work-191-239/migration/app/controllers/", "/home/rubys/git/awdwr/work-191-239/migration/app", "/home/rubys/git/awdwr/work-191-239/migration/app/models", "/home/rubys/git/awdwr/work-191-239/migration/app/controllers", "/home/rubys/git/awdwr/work-191-239/migration/app/helpers", "/home/rubys/git/awdwr/work-191-239/migration/lib", "/home/rubys/git/awdwr/work-191-239/migration/vendor", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/railties/lib/../builtin/rails_info/", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/railties", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/railties/lib", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/activesupport/lib", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/actionpack/lib", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/activerecord/lib", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/actionmailer/lib", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/activeresource/lib", "/home/rubys/git/gorp/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/memcache-client-1.8.3/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/memcache-client-1.8.3/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/i18n-0.4.0.beta1/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/mime-types-1.16/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/rack-mount-0.6.3/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/text-format-1.0.0/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/rack-test-0.5.3/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/abstract-1.0.0/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/rdoc-2.5.8/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/rdoc-2.5.8/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/text-hyphen-1.0.0/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/text-hyphen-1.0.0/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/net-scp-1.0.2/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/bundler-1.0.0.rc.6/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/bundler-1.0.0.rc.6/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/thor-0.13.6/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/thor-0.13.6/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/highline-1.5.2/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/rack-1.1.0/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/rack-1.1.0/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/treetop-1.4.5/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/treetop-1.4.5/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/capistrano-2.5.18/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/capistrano-2.5.18/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/test-unit-2.0.7/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/test-unit-2.0.7/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/tzinfo-0.3.20/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/net-ssh-gateway-1.0.1/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/sqlite3-ruby-1.2.5/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/sqlite3-ruby-1.2.5/ext", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/sqlite3-ruby-1.2.5/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/arel-0.3.3/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/builder-2.1.2/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/htmlentities-4.2.1/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/net-ssh-2.0.22/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/polyglot-0.3.1/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/will_paginate-3.0.pre/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/net-sftp-2.0.4/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/erubis-2.6.5/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/erubis-2.6.5/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/mail-2.2.0/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378@global/gems/rake-0.8.7/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378@global/gems/rake-0.8.7/lib", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/site_ruby/1.9.1", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/site_ruby/1.9.1/i686-linux", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/site_ruby", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/vendor_ruby/1.9.1", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/vendor_ruby/1.9.1/i686-linux", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/vendor_ruby", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/1.9.1", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/1.9.1/i686-linux", ".", "/home/rubys/git/awdwr/data/code/e1/ar"]
>> require "connect"
=> true
>> require "logger"
=> []
 
>> #ActiveRecord::Base.logger = Logger.new(STDERR)
 
?> require "rubygems"
=> []
>> require "active_record"
=> []
 
 
>> ActiveRecord::Schema.define do 
?>   create_table :accounts, :force => true do |t|
?>     t.string  :number
>>     t.decimal :balance, :precision => 10, :scale => 2, :default => 0
>>   end
>> end
-- create_table(:accounts, {:force=>true})
   -> 15.7583s
=> nil
 
 
?> class Account < ActiveRecord::Base
>>   validate :price_must_be_at_least_a_cent
 
>>   def self.transfer(from, to, amount)
>>     transaction(from, to) do
?>       from.withdraw(amount)
>>       to.deposit(amount)
>>     end
>>   end
 
?>   def withdraw(amount)
>>     adjust_balance_and_save(-amount)
>>   end
 
>>   def deposit(amount)
>>     adjust_balance_and_save(amount)
>>   end
 
>>   private
 
>>   def adjust_balance_and_save(amount)
>>     self.balance += amount
>>     save!
>>   end
 
>>   def price_must_be_at_least_a_cent
>>     errors.add(:balance, "is negative") if balance < 0
>>   end
>> end
=> nil
 
?>   def adjust_balance_and_save(amount)
>>     self.balance += amount
>>   end
=> nil
 
?> peter = Account.create(:balance => 100, :number => "12345")
=> #<Account id: 1, number: "12345", balance: #<BigDecimal:84807b8,'0.1E3',4(8)>>
>> paul  = Account.create(:balance => 200, :number => "54321")
=> #<Account id: 2, number: "54321", balance: #<BigDecimal:83cb040,'0.2E3',4(8)>>
 
>> case ARGV[0] || "1"
 
>> when "1"
>>   Account.transaction do
?>     paul.deposit(10)
>>     peter.withdraw(10)
>>   end
 
>> when "2"
>>   Account.transaction do
?>     paul.deposit(350)
>>     peter.withdraw(350)
>>   end
 
>> when "3"
>>   begin
?>     Account.transaction do
?>       paul.deposit(350)
>>       peter.withdraw(350)
>>     end
>>   rescue
>>     puts "Transfer aborted"
>>   end
 
>>   puts "Paul has #{paul.balance}"
>>   puts "Peter has #{peter.balance}"
 
>> when "4"
>>   begin
?>     Account.transaction(peter, paul) do
?>       paul.deposit(350)
>>       peter.withdraw(350)
>>     end
>>   rescue
>>     puts "Transfer aborted"
>>   end
 
>>   puts "Paul has #{paul.balance}"
>>   puts "Peter has #{peter.balance}"
 
>> when "5"
>>   Account.transfer(peter, paul, 350) rescue  puts "Transfer aborted"
 
>>   puts "Paul has #{paul.balance}"
>>   puts "Peter has #{peter.balance}"
 
>> end
Transfer aborted
Paul has 200.0
Peter has 100.0
=> nil
 
 
 
>> >> => nil
irb e1/ar/transactions.rb 5
>> $: << File.dirname(__FILE__)
=> ["/home/rubys/git/awdwr/work-191-239/migration/app/controllers/", "/home/rubys/git/awdwr/work-191-239/migration/app", "/home/rubys/git/awdwr/work-191-239/migration/app/models", "/home/rubys/git/awdwr/work-191-239/migration/app/controllers", "/home/rubys/git/awdwr/work-191-239/migration/app/helpers", "/home/rubys/git/awdwr/work-191-239/migration/lib", "/home/rubys/git/awdwr/work-191-239/migration/vendor", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/railties/lib/../builtin/rails_info/", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/railties", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/railties/lib", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/activesupport/lib", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/actionpack/lib", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/activerecord/lib", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/actionmailer/lib", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/activeresource/lib", "/home/rubys/git/gorp/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/memcache-client-1.8.3/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/memcache-client-1.8.3/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/i18n-0.4.0.beta1/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/mime-types-1.16/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/rack-mount-0.6.3/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/text-format-1.0.0/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/rack-test-0.5.3/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/abstract-1.0.0/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/rdoc-2.5.8/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/rdoc-2.5.8/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/text-hyphen-1.0.0/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/text-hyphen-1.0.0/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/net-scp-1.0.2/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/bundler-1.0.0.rc.6/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/bundler-1.0.0.rc.6/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/thor-0.13.6/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/thor-0.13.6/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/highline-1.5.2/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/rack-1.1.0/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/rack-1.1.0/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/treetop-1.4.5/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/treetop-1.4.5/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/capistrano-2.5.18/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/capistrano-2.5.18/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/test-unit-2.0.7/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/test-unit-2.0.7/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/tzinfo-0.3.20/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/net-ssh-gateway-1.0.1/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/sqlite3-ruby-1.2.5/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/sqlite3-ruby-1.2.5/ext", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/sqlite3-ruby-1.2.5/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/arel-0.3.3/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/builder-2.1.2/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/htmlentities-4.2.1/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/net-ssh-2.0.22/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/polyglot-0.3.1/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/will_paginate-3.0.pre/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/net-sftp-2.0.4/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/erubis-2.6.5/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/erubis-2.6.5/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/mail-2.2.0/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378@global/gems/rake-0.8.7/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378@global/gems/rake-0.8.7/lib", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/site_ruby/1.9.1", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/site_ruby/1.9.1/i686-linux", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/site_ruby", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/vendor_ruby/1.9.1", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/vendor_ruby/1.9.1/i686-linux", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/vendor_ruby", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/1.9.1", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/1.9.1/i686-linux", ".", "/home/rubys/git/awdwr/data/code/e1/ar"]
>> require "connect"
=> true
>> require "logger"
=> []
 
>> #ActiveRecord::Base.logger = Logger.new(STDERR)
 
?> require "rubygems"
=> []
>> require "active_record"
=> []
 
 
>> ActiveRecord::Schema.define do 
?>   create_table :accounts, :force => true do |t|
?>     t.string  :number
>>     t.decimal :balance, :precision => 10, :scale => 2, :default => 0
>>   end
>> end
-- create_table(:accounts, {:force=>true})
   -> 8.8459s
=> nil
 
 
?> class Account < ActiveRecord::Base
>>   validate :price_must_be_at_least_a_cent
 
>>   def self.transfer(from, to, amount)
>>     transaction(from, to) do
?>       from.withdraw(amount)
>>       to.deposit(amount)
>>     end
>>   end
 
?>   def withdraw(amount)
>>     adjust_balance_and_save(-amount)
>>   end
 
>>   def deposit(amount)
>>     adjust_balance_and_save(amount)
>>   end
 
>>   private
 
>>   def adjust_balance_and_save(amount)
>>     self.balance += amount
>>     save!
>>   end
 
>>   def price_must_be_at_least_a_cent
>>     errors.add(:balance, "is negative") if balance < 0
>>   end
>> end
=> nil
 
?>   def adjust_balance_and_save(amount)
>>     self.balance += amount
>>   end
=> nil
 
?> peter = Account.create(:balance => 100, :number => "12345")
=> #<Account id: 1, number: "12345", balance: #<BigDecimal:84e830c,'0.1E3',4(8)>>
>> paul  = Account.create(:balance => 200, :number => "54321")
=> #<Account id: 2, number: "54321", balance: #<BigDecimal:83cb238,'0.2E3',4(8)>>
 
>> case ARGV[0] || "1"
 
>> when "1"
>>   Account.transaction do
?>     paul.deposit(10)
>>     peter.withdraw(10)
>>   end
 
>> when "2"
>>   Account.transaction do
?>     paul.deposit(350)
>>     peter.withdraw(350)
>>   end
 
>> when "3"
>>   begin
?>     Account.transaction do
?>       paul.deposit(350)
>>       peter.withdraw(350)
>>     end
>>   rescue
>>     puts "Transfer aborted"
>>   end
 
>>   puts "Paul has #{paul.balance}"
>>   puts "Peter has #{peter.balance}"
 
>> when "4"
>>   begin
?>     Account.transaction(peter, paul) do
?>       paul.deposit(350)
>>       peter.withdraw(350)
>>     end
>>   rescue
>>     puts "Transfer aborted"
>>   end
 
>>   puts "Paul has #{paul.balance}"
>>   puts "Peter has #{peter.balance}"
 
>> when "5"
>>   Account.transfer(peter, paul, 350) rescue  puts "Transfer aborted"
 
>>   puts "Paul has #{paul.balance}"
>>   puts "Peter has #{peter.balance}"
 
>> end
Transfer aborted
Paul has 200.0
Peter has 100.0
=> nil
 
 
 
>> >> => nil
irb e1/ar/optimistic.rb
>> $: << File.dirname(__FILE__)
=> ["/home/rubys/git/awdwr/work-191-239/migration/app/controllers/", "/home/rubys/git/awdwr/work-191-239/migration/app", "/home/rubys/git/awdwr/work-191-239/migration/app/models", "/home/rubys/git/awdwr/work-191-239/migration/app/controllers", "/home/rubys/git/awdwr/work-191-239/migration/app/helpers", "/home/rubys/git/awdwr/work-191-239/migration/lib", "/home/rubys/git/awdwr/work-191-239/migration/vendor", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/railties/lib/../builtin/rails_info/", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/railties", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/railties/lib", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/activesupport/lib", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/actionpack/lib", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/activerecord/lib", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/actionmailer/lib", "/home/rubys/git/awdwr/work-191-239/migration/vendor/rails/activeresource/lib", "/home/rubys/git/gorp/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/memcache-client-1.8.3/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/memcache-client-1.8.3/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/i18n-0.4.0.beta1/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/mime-types-1.16/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/rack-mount-0.6.3/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/text-format-1.0.0/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/rack-test-0.5.3/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/abstract-1.0.0/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/rdoc-2.5.8/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/rdoc-2.5.8/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/text-hyphen-1.0.0/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/text-hyphen-1.0.0/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/net-scp-1.0.2/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/bundler-1.0.0.rc.6/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/bundler-1.0.0.rc.6/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/thor-0.13.6/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/thor-0.13.6/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/highline-1.5.2/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/rack-1.1.0/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/rack-1.1.0/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/treetop-1.4.5/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/treetop-1.4.5/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/capistrano-2.5.18/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/capistrano-2.5.18/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/test-unit-2.0.7/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/test-unit-2.0.7/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/tzinfo-0.3.20/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/net-ssh-gateway-1.0.1/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/sqlite3-ruby-1.2.5/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/sqlite3-ruby-1.2.5/ext", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/sqlite3-ruby-1.2.5/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/arel-0.3.3/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/builder-2.1.2/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/htmlentities-4.2.1/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/net-ssh-2.0.22/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/polyglot-0.3.1/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/will_paginate-3.0.pre/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/net-sftp-2.0.4/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/erubis-2.6.5/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/erubis-2.6.5/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378/gems/mail-2.2.0/lib", "/home/rubys/.rvm/gems/ruby-1.9.1-p378@global/gems/rake-0.8.7/bin", "/home/rubys/.rvm/gems/ruby-1.9.1-p378@global/gems/rake-0.8.7/lib", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/site_ruby/1.9.1", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/site_ruby/1.9.1/i686-linux", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/site_ruby", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/vendor_ruby/1.9.1", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/vendor_ruby/1.9.1/i686-linux", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/vendor_ruby", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/1.9.1", "/home/rubys/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/1.9.1/i686-linux", ".", "/home/rubys/git/awdwr/data/code/e1/ar"]
>> require "connect"
=> true
 
>> require "rubygems"
=> []
>> require "active_record"
=> []
 
>> ActiveRecord::Schema.define do
?>   create_table :counters, :force => true do |t|
?>     t.integer :count
>>     t.integer :lock_version, :default => 0
>>   end
>> end
-- create_table(:counters, {:force=>true})
   -> 5.1320s
=> nil
 
 
?> class Counter < ActiveRecord::Base
>> end
=> nil
 
>> Counter.delete_all
=> 0
>> Counter.create(:count => 0)
=> #<Counter id: 1, count: 0, lock_version: 0>
 
>> count1 = Counter.find(:first)
=> #<Counter id: 1, count: 0, lock_version: 0>
>> count2 = Counter.find(:first)
=> #<Counter id: 1, count: 0, lock_version: 0>
 
>> count1.count += 3 
=> 3
>> count1.save
=> true
 
>> count2.count += 4 
=> 4
>> count2.save
ActiveRecord::StaleObjectError: Attempted to update a stale object: Counter
	from /home/rubys/git/awdwr/work-191-239/migration/vendor/rails/activerecord/lib/active_record/locking/optimistic.rb:100:in `update_with_lock'
	from /home/rubys/git/awdwr/work-191-239/migration/vendor/rails/activerecord/lib/active_record/dirty.rb:146:in `update_with_dirty'
	from /home/rubys/git/awdwr/work-191-239/migration/vendor/rails/activerecord/lib/active_record/timestamp.rb:64:in `update_with_timestamps'
	from /home/rubys/git/awdwr/work-191-239/migration/vendor/rails/activerecord/lib/active_record/callbacks.rb:282:in `update_with_callbacks'
	from /home/rubys/git/awdwr/work-191-239/migration/vendor/rails/activerecord/lib/active_record/base.rb:2927:in `create_or_update'
	from /home/rubys/git/awdwr/work-191-239/migration/vendor/rails/activerecord/lib/active_record/callbacks.rb:250:in `create_or_update_with_callbacks'
	from /home/rubys/git/awdwr/work-191-239/migration/vendor/rails/activerecord/lib/active_record/base.rb:2577:in `save'
	from /home/rubys/git/awdwr/work-191-239/migration/vendor/rails/activerecord/lib/active_record/validations.rb:1090:in `save_with_validation'
	from /home/rubys/git/awdwr/work-191-239/migration/vendor/rails/activerecord/lib/active_record/dirty.rb:79:in `save_with_dirty'
	from /home/rubys/git/awdwr/work-191-239/migration/vendor/rails/activerecord/lib/active_record/transactions.rb:229:in `block in with_transaction_returning_status'
	from /home/rubys/git/awdwr/work-191-239/migration/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb:136:in `transaction'
	from /home/rubys/git/awdwr/work-191-239/migration/vendor/rails/activerecord/lib/active_record/transactions.rb:182:in `transaction'
	from /home/rubys/git/awdwr/work-191-239/migration/vendor/rails/activerecord/lib/active_record/transactions.rb:228:in `with_transaction_returning_status'
	from /home/rubys/git/awdwr/work-191-239/migration/vendor/rails/activerecord/lib/active_record/transactions.rb:196:in `block in save_with_transactions'
	from /home/rubys/git/awdwr/work-191-239/migration/vendor/rails/activerecord/lib/active_record/transactions.rb:208:in `rollback_active_record_state!'
	from /home/rubys/git/awdwr/work-191-239/migration/vendor/rails/activerecord/lib/active_record/transactions.rb:196:in `save_with_transactions'
	from /home/rubys/git/awdwr/data/code/e1/ar/optimistic.rb:31
	from /home/rubys/.rvm/rubies/ruby-1.9.1-p378/bin/irb:17:in `<main>'>> #END:optimistic
?> >> => nil

21 Action Controller: Routing and URLs 19 ActiveRecord: Relationships Between Tables