active_record-events 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/README.md +13 -0
- data/lib/active_record/events.rb +15 -22
- data/lib/active_record/events/naming.rb +39 -0
- data/lib/active_record/events/version.rb +1 -1
- data/spec/active_record/events/naming_spec.rb +51 -0
- data/spec/active_record/events_spec.rb +7 -0
- data/spec/dummy/app/models/user.rb +3 -0
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/migrate/20170103215307_create_users.rb +9 -0
- data/spec/dummy/db/schema.rb +7 -1
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/support/factories.rb +1 -0
- metadata +9 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
Njk0YzdlMmY0YzRiMmYxNzdjMmE3OTMyODUwNjIzNjgwZmEzOTZiMg==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
NDNiMmViY2U5NTNmZmY5ZjQ3NzdkMTY5Mjg4YTlmMTJmMTI3NjI3Yw==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
OTlhYzQ1ODkwNjg1ZjNkYjhjZTY3ZTgwZWIyYjgxYTgzNDM1NmJlNmExODEy
|
10
|
+
ZTU1MTYxOTllMDAwNmUwOTM0MTVkM2FlODZlN2ZjNzViOTYzNmFmOTk2NTEw
|
11
|
+
Y2JlNzEzZGUyN2EyMTk4M2Q2YWZiNTQ2ODI5NjAzYWY1ZWMwNjY=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
YWZmMzdhYjNmODJlMmY5ZDExOGE1ODBjNmQ3NTc4YTJmOWZlMjIwODU0ZTMz
|
14
|
+
MmJiZjU1ZTJlYjQyOWI4NDA3N2U2NzZjYWFkNDAxNTIyYTE0MDEyMWExOWQz
|
15
|
+
YTA0MmE4MGQzNzNjMWQwNjQzZGQzMzJmZTE3YzBmNDBjMzdlMDg=
|
data/README.md
CHANGED
@@ -69,6 +69,19 @@ scope :not_completed, -> { where(completed_at: nil) }
|
|
69
69
|
scope :completed, -> { where.not(completed_at: nil) }
|
70
70
|
```
|
71
71
|
|
72
|
+
### Subject
|
73
|
+
|
74
|
+
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.
|
75
|
+
In order to keep method names grammatically correct, you can specify a subject using the `subject` option.
|
76
|
+
|
77
|
+
```ruby
|
78
|
+
class User < ActiveRecord::Base
|
79
|
+
has_event :confirm, subject: :email
|
80
|
+
end
|
81
|
+
```
|
82
|
+
|
83
|
+
This will generate `email_confirmed?`, `confirm_email` and `confirm_email!` methods.
|
84
|
+
|
72
85
|
## See also
|
73
86
|
|
74
87
|
- [ActiveRecord::Enum](http://api.rubyonrails.org/classes/ActiveRecord/Enum.html)
|
data/lib/active_record/events.rb
CHANGED
@@ -1,41 +1,34 @@
|
|
1
1
|
require 'active_support'
|
2
|
-
require '
|
2
|
+
require 'active_record/events/naming'
|
3
3
|
|
4
4
|
module ActiveRecord
|
5
5
|
module Events
|
6
|
-
def self.past_participle(infinitive)
|
7
|
-
options = { tense: :past, aspect: :perfective }
|
8
|
-
infinitive.verb.conjugate(options)
|
9
|
-
end
|
10
|
-
|
11
6
|
def has_events(*names)
|
12
|
-
names.
|
7
|
+
options = names.extract_options!
|
8
|
+
names.each { |n| has_event(n, options) }
|
13
9
|
end
|
14
10
|
|
15
|
-
def has_event(name)
|
16
|
-
|
17
|
-
|
18
|
-
past_participle = _module.past_participle(name)
|
19
|
-
field_name = "#{past_participle}_at"
|
11
|
+
def has_event(name, options = {})
|
12
|
+
naming = Naming.new(name, options)
|
20
13
|
|
21
|
-
define_method("#{
|
22
|
-
self[
|
14
|
+
define_method("#{naming.predicate}?") do
|
15
|
+
self[naming.field].present?
|
23
16
|
end
|
24
17
|
|
25
|
-
define_method(
|
26
|
-
touch(
|
18
|
+
define_method(naming.action) do
|
19
|
+
touch(naming.field) if self[naming.field].blank?
|
27
20
|
end
|
28
21
|
|
29
|
-
define_method("#{
|
30
|
-
touch(
|
22
|
+
define_method("#{naming.action}!") do
|
23
|
+
touch(naming.field)
|
31
24
|
end
|
32
25
|
|
33
|
-
define_singleton_method(
|
34
|
-
where(arel_table[
|
26
|
+
define_singleton_method(naming.scope) do
|
27
|
+
where(arel_table[naming.field].not_eq(nil))
|
35
28
|
end
|
36
29
|
|
37
|
-
define_singleton_method(
|
38
|
-
where(arel_table[
|
30
|
+
define_singleton_method(naming.inverse_scope) do
|
31
|
+
where(arel_table[naming.field].eq(nil))
|
39
32
|
end
|
40
33
|
end
|
41
34
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'verbs'
|
2
|
+
|
3
|
+
module ActiveRecord
|
4
|
+
module Events
|
5
|
+
class Naming
|
6
|
+
def initialize(infinitive, options = {})
|
7
|
+
@infinitive = infinitive
|
8
|
+
@subject = options[:subject].presence
|
9
|
+
end
|
10
|
+
|
11
|
+
def field
|
12
|
+
[@subject, past_participle, 'at'].compact.join('_')
|
13
|
+
end
|
14
|
+
|
15
|
+
def predicate
|
16
|
+
[@subject, past_participle].compact.join('_')
|
17
|
+
end
|
18
|
+
|
19
|
+
def action
|
20
|
+
[@infinitive, @subject].compact.join('_')
|
21
|
+
end
|
22
|
+
|
23
|
+
def scope
|
24
|
+
[@subject, past_participle].compact.join('_')
|
25
|
+
end
|
26
|
+
|
27
|
+
def inverse_scope
|
28
|
+
[@subject, 'not', past_participle].compact.join('_')
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def past_participle
|
34
|
+
options = { tense: :past, aspect: :perfective }
|
35
|
+
@infinitive.verb.conjugate(options)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe ActiveRecord::Events::Naming do
|
4
|
+
context 'without a subject' do
|
5
|
+
subject { described_class.new(:complete) }
|
6
|
+
|
7
|
+
it 'generates a field name' do
|
8
|
+
expect(subject.field).to eq('completed_at')
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'generates a predicate name' do
|
12
|
+
expect(subject.predicate).to eq('completed')
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'generates an action name' do
|
16
|
+
expect(subject.action).to eq('complete')
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'generates a scope name' do
|
20
|
+
expect(subject.scope).to eq('completed')
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'generates an inverse scope name' do
|
24
|
+
expect(subject.inverse_scope).to eq('not_completed')
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'with a subject' do
|
29
|
+
subject { described_class.new(:confirm, subject: :email) }
|
30
|
+
|
31
|
+
it 'generates a field name' do
|
32
|
+
expect(subject.field).to eq('email_confirmed_at')
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'generates a predicate name' do
|
36
|
+
expect(subject.predicate).to eq('email_confirmed')
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'generates an action name' do
|
40
|
+
expect(subject.action).to eq('confirm_email')
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'generates a scope name' do
|
44
|
+
expect(subject.scope).to eq('email_confirmed')
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'generates an inverse scope name' do
|
48
|
+
expect(subject.inverse_scope).to eq('email_not_confirmed')
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -28,4 +28,11 @@ RSpec.describe ActiveRecord::Events do
|
|
28
28
|
expect(Task.not_completed).to include(task)
|
29
29
|
expect(Task.completed).not_to include(task)
|
30
30
|
end
|
31
|
+
|
32
|
+
let(:user) { create(:user) }
|
33
|
+
|
34
|
+
it 'handles a subject' do
|
35
|
+
user.confirm_email
|
36
|
+
expect(user.email_confirmed?).to be(true)
|
37
|
+
end
|
31
38
|
end
|
Binary file
|
data/spec/dummy/db/schema.rb
CHANGED
@@ -11,7 +11,7 @@
|
|
11
11
|
#
|
12
12
|
# It's strongly recommended to check this file into your version control system.
|
13
13
|
|
14
|
-
ActiveRecord::Schema.define(:version =>
|
14
|
+
ActiveRecord::Schema.define(:version => 20170103215307) do
|
15
15
|
|
16
16
|
create_table "tasks", :force => true do |t|
|
17
17
|
t.datetime "completed_at"
|
@@ -19,4 +19,10 @@ ActiveRecord::Schema.define(:version => 20150813132804) do
|
|
19
19
|
t.datetime "updated_at", :null => false
|
20
20
|
end
|
21
21
|
|
22
|
+
create_table "users", :force => true do |t|
|
23
|
+
t.datetime "email_confirmed_at"
|
24
|
+
t.datetime "created_at", :null => false
|
25
|
+
t.datetime "updated_at", :null => false
|
26
|
+
end
|
27
|
+
|
22
28
|
end
|
data/spec/dummy/db/test.sqlite3
CHANGED
Binary file
|
data/spec/support/factories.rb
CHANGED
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: 1.
|
4
|
+
version: 1.1.0
|
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: 2017-01-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -133,14 +133,18 @@ files:
|
|
133
133
|
- README.md
|
134
134
|
- Rakefile
|
135
135
|
- lib/active_record/events.rb
|
136
|
+
- lib/active_record/events/naming.rb
|
136
137
|
- lib/active_record/events/version.rb
|
138
|
+
- spec/active_record/events/naming_spec.rb
|
137
139
|
- spec/active_record/events_spec.rb
|
138
140
|
- spec/dummy/app/models/task.rb
|
141
|
+
- spec/dummy/app/models/user.rb
|
139
142
|
- spec/dummy/config/boot.rb
|
140
143
|
- spec/dummy/config/database.yml
|
141
144
|
- spec/dummy/config/environment.rb
|
142
145
|
- spec/dummy/db/development.sqlite3
|
143
146
|
- spec/dummy/db/migrate/20150813132804_create_tasks.rb
|
147
|
+
- spec/dummy/db/migrate/20170103215307_create_users.rb
|
144
148
|
- spec/dummy/db/schema.rb
|
145
149
|
- spec/dummy/db/test.sqlite3
|
146
150
|
- spec/spec_helper.rb
|
@@ -170,13 +174,16 @@ signing_key:
|
|
170
174
|
specification_version: 4
|
171
175
|
summary: Manage timestamps in ActiveRecord models
|
172
176
|
test_files:
|
177
|
+
- spec/active_record/events/naming_spec.rb
|
173
178
|
- spec/active_record/events_spec.rb
|
174
179
|
- spec/dummy/app/models/task.rb
|
180
|
+
- spec/dummy/app/models/user.rb
|
175
181
|
- spec/dummy/config/boot.rb
|
176
182
|
- spec/dummy/config/database.yml
|
177
183
|
- spec/dummy/config/environment.rb
|
178
184
|
- spec/dummy/db/development.sqlite3
|
179
185
|
- spec/dummy/db/migrate/20150813132804_create_tasks.rb
|
186
|
+
- spec/dummy/db/migrate/20170103215307_create_users.rb
|
180
187
|
- spec/dummy/db/schema.rb
|
181
188
|
- spec/dummy/db/test.sqlite3
|
182
189
|
- spec/spec_helper.rb
|