active_record-events 4.0.1 → 4.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +23 -1
- data/lib/active_record/events/method_factory.rb +32 -12
- data/lib/active_record/events/version.rb +1 -1
- data/lib/generators/active_record/event/event_generator.rb +5 -2
- data/spec/active_record/events_spec.rb +104 -0
- data/spec/dummy/app/models/task.rb +3 -1
- data/spec/dummy/db/migrate/20220609015338_add_expired_at_to_tasks.rb +5 -0
- data/spec/dummy/db/migrate/20230308160359_add_notified_on_to_tasks.rb +5 -0
- data/spec/dummy/db/schema.rb +8 -6
- data/spec/generators/active_record/event/event_generator_spec.rb +8 -2
- data/spec/spec_helper.rb +13 -2
- metadata +35 -17
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7ec4cd90a44c6c550a55b4fed0e50686380441cb86a4089a9716d8d5db350984
|
|
4
|
+
data.tar.gz: bf03cc5c153173f2bf842d240374e00e7a94957fcdd4b855dab0a00fc4999a12
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7c567f576431e641cd39dad28b71c033093b8cd51e368003ec93b1a44ff1177ac0272a257d1b73b2398072aeb4d962d568865bbd110e2116085d76b513c5da3a
|
|
7
|
+
data.tar.gz: 1b83157999bf3ad63a76475fcf4b011f0f95cd19d83792f1db2a9f5eaedcca178a69fcfccb01898f7d9452ed06d2ba1c28cac3bb0fe657f5e6ed7304b2db4dd2
|
data/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# ActiveRecord::Events [](https://rubygems.org/gems/active_record-events) [](https://rubygems.org/gems/active_record-events) [](https://github.com/pienkowb/active_record-events/actions/workflows/test.yml?query=branch%3Adevelop) [](https://coveralls.io/github/pienkowb/active_record-events) [](https://codeclimate.com/github/pienkowb/active_record-events)
|
|
2
2
|
|
|
3
3
|
An ActiveRecord extension providing convenience methods for timestamp management.
|
|
4
4
|
|
|
@@ -119,6 +119,26 @@ has_event :complete, field_name: :completion_time
|
|
|
119
119
|
|
|
120
120
|
Note that the `field_name` option takes precedence over the `field_type` option.
|
|
121
121
|
|
|
122
|
+
### Comparison strategy
|
|
123
|
+
|
|
124
|
+
By default the timestamp's presence will dictate the behavior. However in some cases you may want to check against the current time.
|
|
125
|
+
|
|
126
|
+
You can do this with the `strategy` option, which can be either `presence` or `time_comparison`:
|
|
127
|
+
|
|
128
|
+
```ruby
|
|
129
|
+
has_event :complete, strategy: :time_comparison
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
**Example:**
|
|
133
|
+
|
|
134
|
+
```ruby
|
|
135
|
+
task.completed_at = 1.hour.ago
|
|
136
|
+
task.completed? # => true
|
|
137
|
+
|
|
138
|
+
task.completed_at = 1.hour.from_now
|
|
139
|
+
task.completed? # => false
|
|
140
|
+
```
|
|
141
|
+
|
|
122
142
|
### Specifying an object
|
|
123
143
|
|
|
124
144
|
There are events which do not relate to a model itself but to one of its attributes – take the `User` model with the `email_confirmed_at` field as an example.
|
|
@@ -208,6 +228,8 @@ end
|
|
|
208
228
|
- [Tomasz Skupiński](https://github.com/tskupinski)
|
|
209
229
|
- [Oskar Janusz](https://github.com/oskaror)
|
|
210
230
|
- [Mike Rogers](https://github.com/MikeRogers0)
|
|
231
|
+
- [Spencer Rogers](https://github.com/serogers)
|
|
232
|
+
- [Benno Bielmeier](https://github.com/bbenno)
|
|
211
233
|
|
|
212
234
|
## See also
|
|
213
235
|
|
|
@@ -6,11 +6,13 @@ module ActiveRecord
|
|
|
6
6
|
def initialize(event_name, options)
|
|
7
7
|
@options = options
|
|
8
8
|
@naming = Naming.new(event_name, options)
|
|
9
|
+
@strategy = options[:strategy].try(:to_sym)
|
|
10
|
+
@field_type = options[:field_type].try(:to_sym)
|
|
9
11
|
end
|
|
10
12
|
|
|
11
13
|
def instance_methods
|
|
12
14
|
Module.new.tap do |module_|
|
|
13
|
-
define_predicate_method(module_, naming)
|
|
15
|
+
define_predicate_method(module_, naming, strategy)
|
|
14
16
|
define_inverse_predicate_method(module_, naming)
|
|
15
17
|
|
|
16
18
|
define_action_method(module_, naming)
|
|
@@ -20,11 +22,13 @@ module ActiveRecord
|
|
|
20
22
|
|
|
21
23
|
def class_methods
|
|
22
24
|
Module.new.tap do |module_|
|
|
23
|
-
|
|
25
|
+
time_class = field_type == :date ? Date : Time
|
|
26
|
+
|
|
27
|
+
define_collective_action_method(module_, naming, time_class)
|
|
24
28
|
|
|
25
29
|
unless options[:skip_scopes]
|
|
26
|
-
define_scope_method(module_, naming)
|
|
27
|
-
define_inverse_scope_method(module_, naming)
|
|
30
|
+
define_scope_method(module_, naming, strategy, time_class)
|
|
31
|
+
define_inverse_scope_method(module_, naming, strategy, time_class)
|
|
28
32
|
end
|
|
29
33
|
end
|
|
30
34
|
end
|
|
@@ -33,10 +37,16 @@ module ActiveRecord
|
|
|
33
37
|
|
|
34
38
|
attr_reader :options
|
|
35
39
|
attr_reader :naming
|
|
40
|
+
attr_reader :strategy
|
|
41
|
+
attr_reader :field_type
|
|
36
42
|
|
|
37
|
-
def define_predicate_method(module_, naming)
|
|
43
|
+
def define_predicate_method(module_, naming, strategy)
|
|
38
44
|
module_.send(:define_method, naming.predicate) do
|
|
39
|
-
|
|
45
|
+
if strategy == :time_comparison
|
|
46
|
+
self[naming.field].present? && !self[naming.field].future?
|
|
47
|
+
else
|
|
48
|
+
self[naming.field].present?
|
|
49
|
+
end
|
|
40
50
|
end
|
|
41
51
|
end
|
|
42
52
|
|
|
@@ -62,25 +72,35 @@ module ActiveRecord
|
|
|
62
72
|
end
|
|
63
73
|
end
|
|
64
74
|
|
|
65
|
-
def define_collective_action_method(module_, naming)
|
|
75
|
+
def define_collective_action_method(module_, naming, time_class)
|
|
66
76
|
module_.send(:define_method, naming.collective_action) do
|
|
67
77
|
if respond_to?(:touch_all)
|
|
68
78
|
touch_all(naming.field)
|
|
69
79
|
else
|
|
70
|
-
update_all(naming.field =>
|
|
80
|
+
update_all(naming.field => time_class.current)
|
|
71
81
|
end
|
|
72
82
|
end
|
|
73
83
|
end
|
|
74
84
|
|
|
75
|
-
def define_scope_method(module_, naming)
|
|
85
|
+
def define_scope_method(module_, naming, strategy, time_class)
|
|
76
86
|
module_.send(:define_method, naming.scope) do
|
|
77
|
-
|
|
87
|
+
if strategy == :time_comparison
|
|
88
|
+
where(arel_table[naming.field].lteq(time_class.current))
|
|
89
|
+
else
|
|
90
|
+
where(arel_table[naming.field].not_eq(nil))
|
|
91
|
+
end
|
|
78
92
|
end
|
|
79
93
|
end
|
|
80
94
|
|
|
81
|
-
def define_inverse_scope_method(module_, naming)
|
|
95
|
+
def define_inverse_scope_method(module_, naming, strategy, time_class)
|
|
82
96
|
module_.send(:define_method, naming.inverse_scope) do
|
|
83
|
-
|
|
97
|
+
arel_field = arel_table[naming.field]
|
|
98
|
+
|
|
99
|
+
if strategy == :time_comparison
|
|
100
|
+
where(arel_field.eq(nil).or(arel_field.gt(time_class.current)))
|
|
101
|
+
else
|
|
102
|
+
where(arel_field.eq(nil))
|
|
103
|
+
end
|
|
84
104
|
end
|
|
85
105
|
end
|
|
86
106
|
end
|
|
@@ -6,7 +6,7 @@ require 'active_record/events/macro'
|
|
|
6
6
|
module ActiveRecord
|
|
7
7
|
module Generators
|
|
8
8
|
class EventGenerator < Rails::Generators::Base
|
|
9
|
-
MACRO_OPTIONS = %w[object field_type skip_scopes].freeze
|
|
9
|
+
MACRO_OPTIONS = %w[object field_type skip_scopes strategy].freeze
|
|
10
10
|
|
|
11
11
|
argument :model_name, type: :string
|
|
12
12
|
argument :event_name, type: :string
|
|
@@ -17,6 +17,8 @@ module ActiveRecord
|
|
|
17
17
|
desc: 'The field type (datetime or date)'
|
|
18
18
|
class_option :object, type: :string,
|
|
19
19
|
desc: 'The name of the object'
|
|
20
|
+
class_option :strategy, type: :string,
|
|
21
|
+
desc: 'The comparison strategy (presence or time_comparison)'
|
|
20
22
|
|
|
21
23
|
source_root File.expand_path('templates', __dir__)
|
|
22
24
|
|
|
@@ -38,8 +40,9 @@ module ActiveRecord
|
|
|
38
40
|
|
|
39
41
|
macro_options = options.slice(*MACRO_OPTIONS)
|
|
40
42
|
macro = ActiveRecord::Events::Macro.new(event_name, macro_options)
|
|
43
|
+
pattern = /^\s*class\s.+\n/
|
|
41
44
|
|
|
42
|
-
inject_into_file model_file_path, "\s\s#{macro}\n", after:
|
|
45
|
+
inject_into_file model_file_path, "\s\s#{macro}\n", after: pattern
|
|
43
46
|
end
|
|
44
47
|
|
|
45
48
|
private
|
|
@@ -71,4 +71,108 @@ RSpec.describe ActiveRecord::Events do
|
|
|
71
71
|
|
|
72
72
|
expect(task.reload).to be_completed
|
|
73
73
|
end
|
|
74
|
+
|
|
75
|
+
describe 'time comparison strategy' do
|
|
76
|
+
it 'defines a predicate method comparing against current time' do
|
|
77
|
+
task.update!(expired_at: 1.hour.from_now)
|
|
78
|
+
expect(task.expired?).to eq(false)
|
|
79
|
+
|
|
80
|
+
task.update!(expired_at: 1.hour.ago)
|
|
81
|
+
expect(task.expired?).to eq(true)
|
|
82
|
+
|
|
83
|
+
task.update!(expired_at: nil)
|
|
84
|
+
expect(task.expired?).to eq(false)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
it 'defines an inverse predicate method comparing against current time' do
|
|
88
|
+
task.update!(expired_at: 1.hour.from_now)
|
|
89
|
+
expect(task.not_expired?).to eq(true)
|
|
90
|
+
|
|
91
|
+
task.update!(expired_at: 1.hour.ago)
|
|
92
|
+
expect(task.not_expired?).to eq(false)
|
|
93
|
+
|
|
94
|
+
task.update!(expired_at: nil)
|
|
95
|
+
expect(task.not_expired?).to eq(true)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
it 'defines a scope comparing against current time' do
|
|
99
|
+
task.update!(expired_at: 1.hour.from_now)
|
|
100
|
+
expect(Task.expired).not_to include(task)
|
|
101
|
+
|
|
102
|
+
task.update!(expired_at: 1.hour.ago)
|
|
103
|
+
expect(Task.expired).to include(task)
|
|
104
|
+
|
|
105
|
+
task.update!(expired_at: nil)
|
|
106
|
+
expect(Task.expired).not_to include(task)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
it 'defines an inverse scope comparing against current time' do
|
|
110
|
+
task.update!(expired_at: 1.hour.from_now)
|
|
111
|
+
expect(Task.not_expired).to include(task)
|
|
112
|
+
|
|
113
|
+
task.update!(expired_at: 1.hour.ago)
|
|
114
|
+
expect(Task.not_expired).not_to include(task)
|
|
115
|
+
|
|
116
|
+
task.update!(expired_at: nil)
|
|
117
|
+
expect(Task.not_expired).to include(task)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
context 'with a date field' do
|
|
121
|
+
it 'defines a predicate method comparing against current date' do
|
|
122
|
+
task.update!(notified_on: Date.yesterday)
|
|
123
|
+
expect(task.notified?).to eq(true)
|
|
124
|
+
|
|
125
|
+
task.update!(notified_on: Date.today)
|
|
126
|
+
expect(task.notified?).to eq(true)
|
|
127
|
+
|
|
128
|
+
task.update!(notified_on: Date.tomorrow)
|
|
129
|
+
expect(task.notified?).to eq(false)
|
|
130
|
+
|
|
131
|
+
task.update!(notified_on: nil)
|
|
132
|
+
expect(task.notified?).to eq(false)
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
it 'defines an inverse predicate method comparing against current date' do
|
|
136
|
+
task.update!(notified_on: Date.yesterday)
|
|
137
|
+
expect(task.not_notified?).to eq(false)
|
|
138
|
+
|
|
139
|
+
task.update!(notified_on: Date.today)
|
|
140
|
+
expect(task.not_notified?).to eq(false)
|
|
141
|
+
|
|
142
|
+
task.update!(notified_on: Date.tomorrow)
|
|
143
|
+
expect(task.not_notified?).to eq(true)
|
|
144
|
+
|
|
145
|
+
task.update!(notified_on: nil)
|
|
146
|
+
expect(task.not_notified?).to eq(true)
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
it 'defines a scope comparing against current date' do
|
|
150
|
+
task.update!(notified_on: Date.yesterday)
|
|
151
|
+
expect(Task.notified).to include(task)
|
|
152
|
+
|
|
153
|
+
task.update!(notified_on: Date.today)
|
|
154
|
+
expect(Task.notified).to include(task)
|
|
155
|
+
|
|
156
|
+
task.update!(notified_on: Date.tomorrow)
|
|
157
|
+
expect(Task.notified).not_to include(task)
|
|
158
|
+
|
|
159
|
+
task.update!(notified_on: nil)
|
|
160
|
+
expect(Task.notified).not_to include(task)
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
it 'defines an inverse scope comparing against current date' do
|
|
164
|
+
task.update!(notified_on: Date.yesterday)
|
|
165
|
+
expect(Task.not_notified).not_to include(task)
|
|
166
|
+
|
|
167
|
+
task.update!(notified_on: Date.today)
|
|
168
|
+
expect(Task.not_notified).not_to include(task)
|
|
169
|
+
|
|
170
|
+
task.update!(notified_on: Date.tomorrow)
|
|
171
|
+
expect(Task.not_notified).to include(task)
|
|
172
|
+
|
|
173
|
+
task.update!(notified_on: nil)
|
|
174
|
+
expect(Task.not_notified).to include(task)
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
end
|
|
74
178
|
end
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
class Task < ActiveRecord::Base
|
|
2
2
|
has_event :complete
|
|
3
|
-
|
|
3
|
+
has_event :archive, skip_scopes: true
|
|
4
|
+
has_event :expire, strategy: :time_comparison
|
|
5
|
+
has_event :notify, field_type: :date, strategy: :time_comparison
|
|
4
6
|
|
|
5
7
|
def complete!
|
|
6
8
|
super
|
data/spec/dummy/db/schema.rb
CHANGED
|
@@ -2,20 +2,22 @@
|
|
|
2
2
|
# of editing this file, please use the migrations feature of Active Record to
|
|
3
3
|
# incrementally modify your database, and then regenerate this schema definition.
|
|
4
4
|
#
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
#
|
|
8
|
-
# from scratch.
|
|
9
|
-
#
|
|
5
|
+
# This file is the source Rails uses to define your schema when running `bin/rails
|
|
6
|
+
# db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to
|
|
7
|
+
# be faster and is potentially less error prone than running all of your
|
|
8
|
+
# migrations from scratch. Old migrations may fail to apply correctly if those
|
|
9
|
+
# migrations use external dependencies or application code.
|
|
10
10
|
#
|
|
11
11
|
# It's strongly recommended that you check this file into your version control system.
|
|
12
12
|
|
|
13
|
-
ActiveRecord::Schema.define(version:
|
|
13
|
+
ActiveRecord::Schema.define(version: 2023_03_08_160359) do
|
|
14
14
|
|
|
15
15
|
create_table "tasks", force: :cascade do |t|
|
|
16
16
|
t.datetime "completed_at"
|
|
17
17
|
t.datetime "created_at", null: false
|
|
18
18
|
t.datetime "updated_at", null: false
|
|
19
|
+
t.datetime "expired_at"
|
|
20
|
+
t.date "notified_on"
|
|
19
21
|
end
|
|
20
22
|
|
|
21
23
|
end
|
|
@@ -2,7 +2,13 @@ require 'spec_helper'
|
|
|
2
2
|
require 'generators/active_record/event/event_generator'
|
|
3
3
|
|
|
4
4
|
RSpec.describe ActiveRecord::Generators::EventGenerator, type: :generator do
|
|
5
|
-
arguments %w[
|
|
5
|
+
arguments %w[
|
|
6
|
+
task complete
|
|
7
|
+
--field-type=date
|
|
8
|
+
--skip-scopes
|
|
9
|
+
--strategy=time_comparison
|
|
10
|
+
]
|
|
11
|
+
|
|
6
12
|
destination File.expand_path('../../../../tmp', __dir__)
|
|
7
13
|
|
|
8
14
|
before { prepare_destination }
|
|
@@ -30,7 +36,7 @@ RSpec.describe ActiveRecord::Generators::EventGenerator, type: :generator do
|
|
|
30
36
|
|
|
31
37
|
assert_file 'app/models/task.rb', <<-RUBY.strip_heredoc
|
|
32
38
|
class Task < ActiveRecord::Base
|
|
33
|
-
has_event :complete, field_type: :date, skip_scopes: true
|
|
39
|
+
has_event :complete, field_type: :date, skip_scopes: true, strategy: :time_comparison
|
|
34
40
|
end
|
|
35
41
|
RUBY
|
|
36
42
|
end
|
data/spec/spec_helper.rb
CHANGED
|
@@ -1,9 +1,20 @@
|
|
|
1
1
|
ENV['RAILS_ENV'] ||= 'test'
|
|
2
2
|
|
|
3
3
|
require 'bundler/setup'
|
|
4
|
-
require '
|
|
4
|
+
require 'simplecov'
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
SimpleCov.start do
|
|
7
|
+
if ENV['CI']
|
|
8
|
+
require 'simplecov-lcov'
|
|
9
|
+
|
|
10
|
+
SimpleCov::Formatter::LcovFormatter.config do |config|
|
|
11
|
+
config.report_with_single_file = true
|
|
12
|
+
config.single_report_path = 'coverage/lcov.info'
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
formatter SimpleCov::Formatter::LcovFormatter
|
|
16
|
+
end
|
|
17
|
+
end
|
|
7
18
|
|
|
8
19
|
require File.expand_path('dummy/config/environment.rb', __dir__)
|
|
9
20
|
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: active_record-events
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 4.
|
|
4
|
+
version: 4.1.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Bartosz Pieńkowski
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2023-03-21 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activerecord
|
|
@@ -52,20 +52,6 @@ dependencies:
|
|
|
52
52
|
- - "~>"
|
|
53
53
|
- !ruby/object:Gem::Version
|
|
54
54
|
version: '2.2'
|
|
55
|
-
- !ruby/object:Gem::Dependency
|
|
56
|
-
name: coveralls
|
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
|
58
|
-
requirements:
|
|
59
|
-
- - "~>"
|
|
60
|
-
- !ruby/object:Gem::Version
|
|
61
|
-
version: '0.8'
|
|
62
|
-
type: :development
|
|
63
|
-
prerelease: false
|
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
-
requirements:
|
|
66
|
-
- - "~>"
|
|
67
|
-
- !ruby/object:Gem::Version
|
|
68
|
-
version: '0.8'
|
|
69
55
|
- !ruby/object:Gem::Dependency
|
|
70
56
|
name: factory_girl
|
|
71
57
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -122,6 +108,34 @@ dependencies:
|
|
|
122
108
|
- - "~>"
|
|
123
109
|
- !ruby/object:Gem::Version
|
|
124
110
|
version: 0.50.0
|
|
111
|
+
- !ruby/object:Gem::Dependency
|
|
112
|
+
name: simplecov
|
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
|
114
|
+
requirements:
|
|
115
|
+
- - "~>"
|
|
116
|
+
- !ruby/object:Gem::Version
|
|
117
|
+
version: 0.16.1
|
|
118
|
+
type: :development
|
|
119
|
+
prerelease: false
|
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
121
|
+
requirements:
|
|
122
|
+
- - "~>"
|
|
123
|
+
- !ruby/object:Gem::Version
|
|
124
|
+
version: 0.16.1
|
|
125
|
+
- !ruby/object:Gem::Dependency
|
|
126
|
+
name: simplecov-lcov
|
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
|
128
|
+
requirements:
|
|
129
|
+
- - "~>"
|
|
130
|
+
- !ruby/object:Gem::Version
|
|
131
|
+
version: 0.7.0
|
|
132
|
+
type: :development
|
|
133
|
+
prerelease: false
|
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
135
|
+
requirements:
|
|
136
|
+
- - "~>"
|
|
137
|
+
- !ruby/object:Gem::Version
|
|
138
|
+
version: 0.7.0
|
|
125
139
|
- !ruby/object:Gem::Dependency
|
|
126
140
|
name: sqlite3
|
|
127
141
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -191,6 +205,8 @@ files:
|
|
|
191
205
|
- spec/dummy/config/database.yml
|
|
192
206
|
- spec/dummy/config/environment.rb
|
|
193
207
|
- spec/dummy/db/migrate/20150813132804_create_tasks.rb
|
|
208
|
+
- spec/dummy/db/migrate/20220609015338_add_expired_at_to_tasks.rb
|
|
209
|
+
- spec/dummy/db/migrate/20230308160359_add_notified_on_to_tasks.rb
|
|
194
210
|
- spec/dummy/db/schema.rb
|
|
195
211
|
- spec/generators/active_record/event/event_generator_spec.rb
|
|
196
212
|
- spec/spec_helper.rb
|
|
@@ -216,7 +232,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
216
232
|
- !ruby/object:Gem::Version
|
|
217
233
|
version: '0'
|
|
218
234
|
requirements: []
|
|
219
|
-
rubygems_version: 3.
|
|
235
|
+
rubygems_version: 3.1.6
|
|
220
236
|
signing_key:
|
|
221
237
|
specification_version: 4
|
|
222
238
|
summary: Manage timestamps in ActiveRecord models
|
|
@@ -228,6 +244,8 @@ test_files:
|
|
|
228
244
|
- spec/dummy/config/boot.rb
|
|
229
245
|
- spec/dummy/db/schema.rb
|
|
230
246
|
- spec/dummy/db/migrate/20150813132804_create_tasks.rb
|
|
247
|
+
- spec/dummy/db/migrate/20220609015338_add_expired_at_to_tasks.rb
|
|
248
|
+
- spec/dummy/db/migrate/20230308160359_add_notified_on_to_tasks.rb
|
|
231
249
|
- spec/active_record/events/method_factory_spec.rb
|
|
232
250
|
- spec/active_record/events/naming_spec.rb
|
|
233
251
|
- spec/active_record/events/macro_spec.rb
|