File: database.rb

package info (click to toggle)
ruby-test-after-commit 0.2.3%2Bgh-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 120 kB
  • ctags: 30
  • sloc: ruby: 333; makefile: 2
file content (180 lines) | stat: -rw-r--r-- 3,699 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# setup database
require 'active_record'

if ActiveRecord::VERSION::MAJOR > 3
  require "rails/observers/activerecord/active_record"
end

ActiveRecord::Base.establish_connection(
  :adapter  => 'sqlite3',
  :database => ':memory:'
)

ActiveRecord::Migration.verbose = false

ActiveRecord::Schema.define(:version => 1) do
  create_table "cars", :force => true do |t|
    t.integer :counter, :default => 0, :null => false
    t.integer :car_id
    t.timestamps
  end

  create_table "addresses", :force => true do |t|
    t.integer :number_of_residents, :default => 0, :null => false
    t.timestamps
  end

  create_table "people", :force => true do |t|
    t.belongs_to :address
    t.timestamps
  end

  create_table "fu_bears", :force => true do |t|
    t.string :name
    t.timestamps
  end
end

module Called
  def called(x=nil)
    @called ||= []
    if x
      @called << x
    else
      @called
    end
  end
end

class Car < ActiveRecord::Base
  extend Called

  has_many :cars

  after_commit :simple_after_commit
  after_commit :simple_after_commit_on_create, :on => :create
  after_commit :save_once, :on => :create, :if => :do_after_create_save
  after_commit :simple_after_commit_on_update, :on => :update
  after_commit :maybe_raise_errors

  after_save :trigger_rollback

  attr_accessor :make_rollback, :raise_error, :do_after_create_save

  def trigger_rollback
    raise ActiveRecord::Rollback if make_rollback
  end

  def self.returning_method_with_transaction
    Car.transaction do
      return Car.create
    end
  end

  private

  def save_once
    update_attributes(:counter => 3) unless counter == 3
    self.class.called :save_once
  end

  def maybe_raise_errors
    if raise_error
      # puts "MAYBE RAISE" # just debugging, but it really does not work ...
      raise "Expected error"
    end
  end

  def simple_after_commit
    self.class.called :always
  end

  def simple_after_commit_on_create
    self.class.called :create
  end

  def simple_after_commit_on_update
    self.class.called :update
  end
end

class CarObserver < ActiveRecord::Observer
  cattr_accessor :recording

  [:after_commit, :after_rollback].each do |action|
    define_method action do |record|
      return unless recording
      Car.called << :observed_after_commit
      Untracked.create!
    end
  end
end

Car.observers = :car_observer
Car.instantiate_observers

class Bar < ActiveRecord::Base
  self.table_name = "cars"
  has_many :bars, :foreign_key => :car_id
end

class MultiBar < ActiveRecord::Base
  extend Called

  self.table_name = "cars"

  after_commit :one, :on => :create
  after_commit :two, :on => :create

  def one
    self.class.called << :one
  end

  def two
    self.class.called << :two
  end
end

class Address < ActiveRecord::Base
  has_many :people

  after_commit :create_residents, :on => :create

  def create_residents
    if ActiveRecord::VERSION::MAJOR == 3
      # stupid hack because nested after_commit is broken on rails 3 and loops
      return if @create_residents
      @create_residents = true
    end

    Person.create!(:address => self)
    Person.create!(:address => self)
  end
end

class Person < ActiveRecord::Base
  belongs_to :address

  after_commit :update_number_of_residents_on_address, :on => :create

  def update_number_of_residents_on_address
    address.update_attributes(:number_of_residents => address.number_of_residents + 1)
  end
end

class Untracked < ActiveRecord::Base
  self.table_name = "cars"
end

class FuBear < ActiveRecord::Base
  extend Called

  self.table_name = "fu_bears"
  validates_presence_of :name

  after_commit :simple_after_commit

  def simple_after_commit
    self.class.called :always
  end
end