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 CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- N2VhZTQxOTNiMmU4MzdmNjgyYjIzNzMwNjMzZjY1MjM3ODJiOGJhZQ==
4
+ Njk0YzdlMmY0YzRiMmYxNzdjMmE3OTMyODUwNjIzNjgwZmEzOTZiMg==
5
5
  data.tar.gz: !binary |-
6
- YzRmYWY5M2JmYmNmMGY0ODdiMTIwY2QyZDdkYjhkZDMxODMzYzM3MQ==
6
+ NDNiMmViY2U5NTNmZmY5ZjQ3NzdkMTY5Mjg4YTlmMTJmMTI3NjI3Yw==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- Y2NjZTY3YmIyMDBjZjNlMmZiNWU1NjdlZGExMTE0ZGViYTg3NWY4YWY3ZmM3
10
- YzBmZjJlNWI4MWFlYWQ0ZWQ5ZmRmZDgxMmI3NTYzM2VlNGZmNGYyYzEyNmE2
11
- ZjQ0YzAzNzhmMjk5ZTE0OGZkNjM2YzAzM2IwNzI5MTkxMTU1MmU=
9
+ OTlhYzQ1ODkwNjg1ZjNkYjhjZTY3ZTgwZWIyYjgxYTgzNDM1NmJlNmExODEy
10
+ ZTU1MTYxOTllMDAwNmUwOTM0MTVkM2FlODZlN2ZjNzViOTYzNmFmOTk2NTEw
11
+ Y2JlNzEzZGUyN2EyMTk4M2Q2YWZiNTQ2ODI5NjAzYWY1ZWMwNjY=
12
12
  data.tar.gz: !binary |-
13
- MDA2M2M3MjY2NzUyYTVhYjJkMmU4ZDhjYmJjNDcxOGU3NDFlNWE5MmFkMDMy
14
- ODdhZTFkOWJlYWEyOTcxNjM5MTMxOGEzMmFmZDBlMDc3NDllYjMzZjRlZThl
15
- ZTM5ZThmZWM3NzE1NjIyOTY1ZTUyZWY1NTE5MmY5MjY2YmQzZTk=
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)
@@ -1,41 +1,34 @@
1
1
  require 'active_support'
2
- require 'verbs'
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.each { |n| has_event(n) }
7
+ options = names.extract_options!
8
+ names.each { |n| has_event(n, options) }
13
9
  end
14
10
 
15
- def has_event(name)
16
- _module = ActiveRecord::Events
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("#{past_participle}?") do
22
- self[field_name].present?
14
+ define_method("#{naming.predicate}?") do
15
+ self[naming.field].present?
23
16
  end
24
17
 
25
- define_method(name) do
26
- touch(field_name) if self[field_name].blank?
18
+ define_method(naming.action) do
19
+ touch(naming.field) if self[naming.field].blank?
27
20
  end
28
21
 
29
- define_method("#{name}!") do
30
- touch(field_name)
22
+ define_method("#{naming.action}!") do
23
+ touch(naming.field)
31
24
  end
32
25
 
33
- define_singleton_method(past_participle) do
34
- where(arel_table[field_name].not_eq(nil))
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("not_#{past_participle}") do
38
- where(arel_table[field_name].eq(nil))
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
@@ -1,5 +1,5 @@
1
1
  module ActiveRecord
2
2
  module Events
3
- VERSION = '1.0.0'
3
+ VERSION = '1.1.0'
4
4
  end
5
5
  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
@@ -0,0 +1,3 @@
1
+ class User < ActiveRecord::Base
2
+ has_event :confirm, subject: :email
3
+ end
@@ -0,0 +1,9 @@
1
+ class CreateUsers < ActiveRecord::Migration
2
+ def change
3
+ create_table :users do |t|
4
+ t.datetime :email_confirmed_at
5
+
6
+ t.timestamps null: false
7
+ end
8
+ end
9
+ end
@@ -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 => 20150813132804) do
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
Binary file
@@ -1,3 +1,4 @@
1
1
  FactoryGirl.define do
2
2
  factory :task
3
+ factory :user
3
4
  end
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.0.0
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: 2016-12-28 00:00:00.000000000 Z
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