transient 1.0.0 → 1.0.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.
- data/History.txt +6 -0
- data/README.rdoc +11 -1
- data/VERSION +1 -1
- data/lib/transient.rb +1 -1
- data/lib/transient/active_record_extensions.rb +16 -18
- data/spec/transient_shared_spec.rb +13 -0
- data/spec/transient_spec.rb +10 -11
- data/transient.gemspec +2 -2
- metadata +2 -2
data/History.txt
CHANGED
data/README.rdoc
CHANGED
@@ -13,6 +13,9 @@ Provides an API for making any ActiveRecord object transient.
|
|
13
13
|
* Convenience methods for transient objects, ie. current?, expired?, expire!, etc.
|
14
14
|
* Callbacks for expiring current 'active' record prior to creating new one where certain configured fields
|
15
15
|
match. See the Transient::ActiveRecordExtensions::InstanceMethods docs for more information.
|
16
|
+
* A callback to populate the expiring at field of a new record with DateTime.now unless a value was explicitly
|
17
|
+
specified for the effective at field.
|
18
|
+
* Automatically adds a presence validation for effective_at to the model.
|
16
19
|
|
17
20
|
|
18
21
|
== REQUIREMENTS
|
@@ -31,7 +34,7 @@ Provides an API for making any ActiveRecord object transient.
|
|
31
34
|
|
32
35
|
Add to environment file:
|
33
36
|
|
34
|
-
config.gem "transient", :version => '1.0.
|
37
|
+
config.gem "transient", :version => '1.0.1', :source => 'http://gemcutter.org'
|
35
38
|
|
36
39
|
Run:
|
37
40
|
|
@@ -40,6 +43,13 @@ Run:
|
|
40
43
|
|
41
44
|
== USAGE
|
42
45
|
|
46
|
+
Add the transient fields to your model:
|
47
|
+
|
48
|
+
def self.up
|
49
|
+
add_column :users, :effective_at, :datetime, :null => false
|
50
|
+
add_column :users, :expiring_at, :datetime
|
51
|
+
end
|
52
|
+
|
43
53
|
Call the macro from your ActiveRecord descendant class:
|
44
54
|
|
45
55
|
class User < ActiveRecord::Base
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0.
|
1
|
+
1.0.1
|
data/lib/transient.rb
CHANGED
@@ -21,16 +21,21 @@ module Transient
|
|
21
21
|
end
|
22
22
|
|
23
23
|
module InstanceMethods
|
24
|
-
def self.included(
|
25
|
-
|
26
|
-
#
|
24
|
+
def self.included( base ) #:nodoc:
|
25
|
+
base.validates_presence_of :effective_at
|
26
|
+
#base.validates_presence_of :expiring_at
|
27
27
|
|
28
|
-
|
29
|
-
#includee.default(:expiring_at) { DateTime.end_of }
|
30
|
-
|
31
|
-
includee.named_scope :current, lambda { { :conditions => ["effective_at <= ? AND (expiring_at IS NULL OR expiring_at > ?)",
|
28
|
+
base.named_scope :effective, lambda { { :conditions => ["effective_at <= ? AND (expiring_at IS NULL OR expiring_at > ?)",
|
32
29
|
DateTime.now.utc, DateTime.now.utc] } }
|
33
30
|
|
31
|
+
base.before_validation_on_create :check_and_set_effective_at
|
32
|
+
|
33
|
+
protected
|
34
|
+
|
35
|
+
def check_and_set_effective_at
|
36
|
+
self[:effective_at] = DateTime.now if self[:effective_at].nil?
|
37
|
+
end
|
38
|
+
|
34
39
|
public
|
35
40
|
|
36
41
|
# Validates this record's effective dates occur in correct sequence (ie. effective_at is before
|
@@ -46,18 +51,11 @@ module Transient
|
|
46
51
|
super
|
47
52
|
end
|
48
53
|
|
49
|
-
# The date this record becomes effective. Returns DateTime.beginning_of for records that have a
|
50
|
-
# nil value in the database.
|
51
|
-
#
|
52
|
-
def effective_at
|
53
|
-
return self[:effective_at].blank? ? DateTime.beginning_of : self[:effective_at]
|
54
|
-
end
|
55
|
-
|
56
54
|
# The date this record expires. Returns DateTime.end_of for records that have a
|
57
55
|
# nil value in the database.
|
58
56
|
#
|
59
57
|
def expiring_at
|
60
|
-
return self[:expiring_at].
|
58
|
+
return self[:expiring_at].nil? ? DateTime.end_of : self[:expiring_at]
|
61
59
|
end
|
62
60
|
|
63
61
|
# The range this record is effective wihtin.
|
@@ -122,8 +120,8 @@ module Transient
|
|
122
120
|
end
|
123
121
|
|
124
122
|
module SingleActive
|
125
|
-
def self.included(
|
126
|
-
|
123
|
+
def self.included( base ) #:nodoc:
|
124
|
+
base.before_create :expire_current_active
|
127
125
|
|
128
126
|
private
|
129
127
|
|
@@ -137,7 +135,7 @@ module Transient
|
|
137
135
|
|
138
136
|
conditions = {}
|
139
137
|
self.transient_options[:single_active].each { |attr| conditions.merge!( attr.to_sym => attributes[attr] ) }
|
140
|
-
old = self.class.
|
138
|
+
old = self.class.effective.first( :conditions => conditions )
|
141
139
|
old.expire! unless old.nil?
|
142
140
|
end
|
143
141
|
end
|
@@ -54,10 +54,23 @@ shared_examples_for "Any transient" do
|
|
54
54
|
@instance.should_not be_past
|
55
55
|
@instance.should be_future
|
56
56
|
end
|
57
|
+
|
58
|
+
it "should respond to :effective" do
|
59
|
+
@klass.respond_to?( :effective ).should be_true
|
60
|
+
end
|
57
61
|
|
58
62
|
it "should invoke callbacks around expire!" do
|
59
63
|
@instance.should_receive(:before_expire!)
|
60
64
|
@instance.should_receive(:after_expire!)
|
61
65
|
@instance.expire!
|
62
66
|
end
|
67
|
+
|
68
|
+
it "should set effective_at to now if it was not explicitly set to something else" do
|
69
|
+
@instance_no_dates.effective_at.should_not be_nil
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should not allow records without an effective_at date to be saved" do
|
73
|
+
@instance_no_dates.effective_at = nil
|
74
|
+
@instance_no_dates.save.should be_false
|
75
|
+
end
|
63
76
|
end
|
data/spec/transient_spec.rb
CHANGED
@@ -12,8 +12,9 @@ describe "Transient" do
|
|
12
12
|
describe "having models descending from ActiveRecord" do
|
13
13
|
describe "that are not single active" do
|
14
14
|
before(:each) do
|
15
|
-
@
|
16
|
-
@instance.
|
15
|
+
@klass = User
|
16
|
+
@instance = @klass.create( :name => 'John Smith', :effective_at => (DateTime.now - 1.days), :expiring_at => DateTime.end_of )
|
17
|
+
@instance_no_dates = @klass.create( :name => 'Jack Smith' )
|
17
18
|
end
|
18
19
|
|
19
20
|
it_should_behave_like "Any transient"
|
@@ -30,34 +31,32 @@ describe "Transient" do
|
|
30
31
|
describe "that are single active" do
|
31
32
|
before(:each) do
|
32
33
|
@klass = ContactNumber
|
33
|
-
@instance = @klass.
|
34
|
-
@
|
34
|
+
@instance = @klass.create( :number => '012345678901', :location => 'home', :effective_at => (DateTime.now - 1.days) )
|
35
|
+
@instance_no_dates = @klass.create( :number => '012345678901', :location => 'home' )
|
35
36
|
end
|
36
37
|
|
37
38
|
it_should_behave_like "Any transient"
|
38
39
|
it_should_behave_like "Any transient that is single active"
|
39
40
|
|
40
41
|
it "should expire the current active before saving a new one" do
|
41
|
-
@new_contact = ContactNumber.
|
42
|
-
@new_contact.save!
|
42
|
+
@new_contact = ContactNumber.create( :number => '019876543210', :location => 'home', :effective_at => DateTime.now )
|
43
43
|
@instance.reload
|
44
44
|
@instance.expired?.should be_true
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
48
48
|
describe "that are single active with check exists" do
|
49
|
-
before
|
49
|
+
before :each do
|
50
50
|
@klass = Address
|
51
|
-
@instance = @klass.
|
52
|
-
@
|
51
|
+
@instance = @klass.create( :street => '26 street', :location => 'home', :effective_at => (DateTime.now - 1.days) )
|
52
|
+
@instance_no_dates = @klass.create( :street => '26 street', :location => 'home' )
|
53
53
|
end
|
54
54
|
|
55
55
|
it_should_behave_like "Any transient"
|
56
56
|
it_should_behave_like "Any transient that is single active"
|
57
57
|
|
58
58
|
it "should expire the current active before saving a new one" do
|
59
|
-
@new_address = Address.
|
60
|
-
@new_address.save!
|
59
|
+
@new_address = Address.create( :street => '27 street', :location => 'home', :effective_at => DateTime.now )
|
61
60
|
@instance.reload
|
62
61
|
@instance.expired?.should be_true
|
63
62
|
end
|
data/transient.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{transient}
|
8
|
-
s.version = "1.0.
|
8
|
+
s.version = "1.0.1"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["C. Jason Harrelson (midas)"]
|
12
|
-
s.date = %q{2009-12-
|
12
|
+
s.date = %q{2009-12-29}
|
13
13
|
s.description = %q{Provides an API for making any ActiveRecord object transient. In addition, provides functionality for models where only a single instance of the model can be current at one time.}
|
14
14
|
s.email = %q{jason@lookforwardenterprises.com}
|
15
15
|
s.extra_rdoc_files = [
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: transient
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- C. Jason Harrelson (midas)
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-12-
|
12
|
+
date: 2009-12-29 00:00:00 -06:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|