123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 |
- #---
- # Excerpted from "Agile Web Development with Rails",
- # published by The Pragmatic Bookshelf.
- # Copyrights apply to this code. It may not be used to create training material,
- # courses, books, articles, and the like. Contact us if you are in doubt.
- # We make no guarantees that this code is fit for any purpose.
- # Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information.
- #---
- #---
- # Excerpted from "Agile Web Development with Rails, 4rd Ed.",
- # published by The Pragmatic Bookshelf.
- # Copyrights apply to this code. It may not be used to create training material,
- # courses, books, articles, and the like. Contact us if you are in doubt.
- # We make no guarantees that this code is fit for any purpose.
- # Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information.
- #---
- $: << File.dirname(__FILE__)
- require "connect"
- 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
- 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
- def adjust_balance_and_save(amount)
- self.balance += amount
- end
- peter = Account.create(:balance => 100, :number => "12345")
- paul = Account.create(:balance => 200, :number => "54321")
- 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
|