act_as_time_as_boolean 0.2.1 → 0.3.0

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.
data/README.md CHANGED
@@ -33,21 +33,31 @@ end
33
33
 
34
34
  item = Item.new
35
35
 
36
- p item.active?
36
+ item.active?
37
37
  #=> false
38
38
 
39
- p item.inactive?
39
+ item.inactive?
40
40
  #=> true
41
41
 
42
42
  item.active = true
43
43
 
44
- p item.active?
44
+ item.active?
45
45
  #=> true
46
46
 
47
- p item.inactive?
47
+ item.inactive?
48
48
  #=> false
49
49
  ```
50
50
 
51
+ #### On a rails app
52
+
53
+ ```ruby
54
+ Item.active
55
+ #=> #<ActiveRecord::Relation [...]>
56
+
57
+ Item.inactive
58
+ #=> #<ActiveRecord::Relation [...]>
59
+ ```
60
+
51
61
  ## Contributing
52
62
 
53
63
  1. Fork repository
@@ -1,12 +1,13 @@
1
1
  module ActAsTimeAsBoolean
2
-
3
2
  def self.included(base)
4
- base.define_singleton_method(:time_as_boolean) do |field, options={}|
3
+ @base = base
4
+
5
+ base.define_singleton_method(:time_as_boolean) do |field, options = {}|
5
6
  ActAsTimeAsBoolean.time_as_boolean_method field, options
6
7
  end
7
8
  end
8
9
 
9
- protected
10
+ protected
10
11
 
11
12
  def self.time_as_boolean_method(field, options)
12
13
  field = field.to_sym
@@ -17,33 +18,59 @@ protected
17
18
  if options[:opposite]
18
19
  ActAsTimeAsBoolean.opposite_getter_method field, options[:opposite]
19
20
  end
21
+
22
+ if ActAsTimeAsBoolean.has_scope_method?
23
+ ActAsTimeAsBoolean.field_scope field
24
+
25
+ if options[:opposite]
26
+ ActAsTimeAsBoolean.opposite_field_scope field, options[:opposite]
27
+ end
28
+ end
20
29
  end
21
30
 
22
31
  def self.field_getter_method(field)
23
- self.send :define_method, field do
32
+ send :define_method, field do
24
33
  !send(:"#{field}_at").nil?
25
34
  end
26
35
 
27
- self.send :alias_method, :"#{field}?", :"#{field}"
36
+ send :alias_method, :"#{field}?", :"#{field}"
28
37
  end
29
38
 
30
39
  def self.field_setter_method(field)
31
- self.send :define_method, :"#{field}=" do |value|
40
+ send :define_method, :"#{field}=" do |value|
32
41
  value = value && value.to_s != '0'
33
- if value && !self.send(field)
42
+ if value && !send(field)
34
43
  send :"#{field}_at=", Time.now
35
44
  true
36
- elsif !value && self.send(field)
45
+ elsif !value && send(field)
37
46
  send :"#{field}_at=", nil
38
47
  end
39
48
  end
40
49
  end
41
50
 
42
51
  def self.opposite_getter_method(field, opposite)
43
- self.send :define_method, :"#{opposite}" do
52
+ send :define_method, :"#{opposite}" do
44
53
  send(:"#{field}_at").nil?
45
54
  end
46
55
 
47
- self.send :alias_method, :"#{opposite}?", :"#{opposite}"
56
+ send :alias_method, :"#{opposite}?", :"#{opposite}"
57
+ end
58
+
59
+ def self.field_scope(field)
60
+ @base.send :scope, field, -> {
61
+ @base.send :where, [ "#{field}_at IS NOT NULL AND #{field}_at <= ?", Time.current]
62
+ }
63
+ end
64
+
65
+ def self.opposite_field_scope(field, opposite)
66
+ @base.send :scope, opposite, -> {
67
+ @base.send :where, [ "#{field}_at IS NULL OR #{field}_at > ?", Time.current]
68
+ }
69
+ end
70
+
71
+ def self.has_scope_method?
72
+ defined?(ActiveRecord::Base) &&
73
+ ActiveRecord::Base.is_a?(Class) &&
74
+ ActiveRecord::Base.methods.include?(:scope)
48
75
  end
49
76
  end
@@ -1,3 +1,3 @@
1
1
  module ActAsTimeAsBoolean
2
- VERSION = '0.2.1'
2
+ VERSION = '0.3.0'
3
3
  end
@@ -13,13 +13,41 @@ class TimeAsBooleanWithOppositeModel
13
13
 
14
14
  attr_accessor :active_at
15
15
 
16
- def initialize(options={})
16
+ def initialize(options = {})
17
17
  @active_at = options[:active_at] || nil
18
18
  end
19
19
 
20
20
  time_as_boolean :active, opposite: :inactive
21
21
  end
22
22
 
23
+ # Awesome mock to test scope
24
+ class ActiveRecord
25
+ end
26
+
27
+ class ActiveRecord::Base
28
+ def self.scope(name, body, &block)
29
+ define_singleton_method name do
30
+ # Nothing to do here, just a mock
31
+ end
32
+ end
33
+ end
34
+
35
+ class InheritedModel < ActiveRecord::Base
36
+ include ActAsTimeAsBoolean
37
+
38
+ attr_accessor :active_at
39
+
40
+ time_as_boolean :active
41
+ end
42
+
43
+ class InheritedModelWithOpposite < ActiveRecord::Base
44
+ include ActAsTimeAsBoolean
45
+
46
+ attr_accessor :active_at
47
+
48
+ time_as_boolean :active, opposite: :inactive
49
+ end
50
+
23
51
  describe ActAsTimeAsBoolean do
24
52
  it 'defines time_as_boolean class method' do
25
53
  SimpleTimeAsBooleanModel.singleton_methods.should include(:time_as_boolean)
@@ -71,6 +99,24 @@ describe ActAsTimeAsBoolean do
71
99
  subject.methods.should include(:inactive?)
72
100
  end
73
101
  end
102
+
103
+ describe 'on a rails app' do
104
+ describe 'with :active param' do
105
+ it 'define active scope' do
106
+ InheritedModel.methods.should include(:active)
107
+ end
108
+ end
109
+
110
+ describe 'with :active and opposite param' do
111
+ it 'define active scope' do
112
+ InheritedModelWithOpposite.methods.should include(:active)
113
+ end
114
+
115
+ it 'define inactive scope' do
116
+ InheritedModelWithOpposite.methods.should include(:inactive)
117
+ end
118
+ end
119
+ end
74
120
  end
75
121
 
76
122
  describe 'using ActAsTimeAsBoolean' do
@@ -133,28 +179,20 @@ describe ActAsTimeAsBoolean do
133
179
  end
134
180
 
135
181
  describe 'calling active=' do
136
- describe 'with true' do
137
- before { subject.active = true }
138
-
139
- it { subject.active_at.class.should == Time }
140
- end
141
-
142
- describe 'with false' do
143
- before { subject.active = false }
182
+ [true, '1'].each do |value|
183
+ describe "with #{value}" do
184
+ before { subject.active = value }
144
185
 
145
- it { subject.active_at.should be_nil }
146
- end
147
-
148
- describe "with '1'" do
149
- before { subject.active = '1' }
150
-
151
- it { subject.active_at.class.should == Time }
186
+ it { subject.active_at.class.should == Time }
187
+ end
152
188
  end
153
189
 
154
- describe "with '0'" do
155
- before { subject.active = '0' }
190
+ [false, '0'].each do |value|
191
+ describe "with #{value}" do
192
+ before { subject.active = value }
156
193
 
157
- it { subject.active_at.should be_nil }
194
+ it { subject.active_at.should be_nil }
195
+ end
158
196
  end
159
197
  end
160
198
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: act_as_time_as_boolean
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-12-06 00:00:00.000000000 Z
12
+ date: 2014-02-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake