transactions.rb 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. #---
  2. # Excerpted from "Agile Web Development with Rails",
  3. # published by The Pragmatic Bookshelf.
  4. # Copyrights apply to this code. It may not be used to create training material,
  5. # courses, books, articles, and the like. Contact us if you are in doubt.
  6. # We make no guarantees that this code is fit for any purpose.
  7. # Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information.
  8. #---
  9. $: << File.dirname(__FILE__)
  10. require "connect"
  11. require "logger"
  12. #ActiveRecord::Base.logger = Logger.new(STDERR)
  13. require "rubygems"
  14. require "active_record"
  15. ActiveRecord::Schema.define do
  16. create_table :accounts, force: true do |t|
  17. t.string :number
  18. t.decimal :balance, precision: 10, scale: 2, default: 0
  19. end
  20. end
  21. class Account < ActiveRecord::Base
  22. validates :balance, numericality: {greater_than_or_equal_to: 0}
  23. def self.transfer(from, to, amount)
  24. transaction(from, to) do
  25. from.withdraw(amount)
  26. to.deposit(amount)
  27. end
  28. end
  29. def withdraw(amount)
  30. adjust_balance_and_save!(-amount)
  31. end
  32. def deposit(amount)
  33. adjust_balance_and_save!(amount)
  34. end
  35. private
  36. def adjust_balance_and_save!(amount)
  37. self.balance += amount
  38. save!
  39. end
  40. end
  41. def adjust_balance_and_save!(amount)
  42. self.balance += amount
  43. end
  44. peter = Account.create(balance: 100, number: "12345")
  45. paul = Account.create(balance: 200, number: "54321")
  46. case ARGV[0] || "1"
  47. when "1"
  48. Account.transaction do
  49. paul.deposit(10)
  50. peter.withdraw(10)
  51. end
  52. when "2"
  53. Account.transaction do
  54. paul.deposit(350)
  55. peter.withdraw(350)
  56. end
  57. when "3"
  58. begin
  59. Account.transaction do
  60. paul.deposit(350)
  61. peter.withdraw(350)
  62. end
  63. rescue
  64. puts "Transfer aborted"
  65. end
  66. puts "Paul has #{paul.balance}"
  67. puts "Peter has #{peter.balance}"
  68. when "4"
  69. begin
  70. Account.transaction(peter, paul) do
  71. paul.deposit(350)
  72. peter.withdraw(350)
  73. end
  74. rescue
  75. puts "Transfer aborted"
  76. end
  77. puts "Paul has #{paul.balance}"
  78. puts "Peter has #{peter.balance}"
  79. when "5"
  80. Account.transfer(peter, paul, 350) rescue puts "Transfer aborted"
  81. puts "Paul has #{paul.balance}"
  82. puts "Peter has #{peter.balance}"
  83. end