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.
@@ -1,3 +1,9 @@
1
+ = 1.0.1 2009-12-29
2
+
3
+ * Added call back to populate effective_at with DateTime.now if it is not explicitly set to something else.
4
+ * Added presence validation to effective_at.
5
+
6
+
1
7
  = 1.0.0 2009-12-26
2
8
 
3
9
  * Initial release Ported from another project.
@@ -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.0', :source => 'http://gemcutter.org'
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.0
1
+ 1.0.1
@@ -4,7 +4,7 @@ require 'date_time_extensions'
4
4
  require 'transient/active_record_extensions'
5
5
 
6
6
  module Transient
7
- VERSION = '1.0.0'
7
+ VERSION = '1.0.1'
8
8
  end
9
9
 
10
10
  ActiveRecord::Base.send( :include, Transient::ActiveRecordExtensions ) if defined?( ActiveRecord::Base )
@@ -21,16 +21,21 @@ module Transient
21
21
  end
22
22
 
23
23
  module InstanceMethods
24
- def self.included( includee ) #:nodoc:
25
- #includee.validates_presence_of :effective_at
26
- #includee.validates_presence_of :expiring_at
24
+ def self.included( base ) #:nodoc:
25
+ base.validates_presence_of :effective_at
26
+ #base.validates_presence_of :expiring_at
27
27
 
28
- #includee.default(:effective_at) { DateTime.beginning_of }
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].blank? ? DateTime.end_of : 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( includee ) #:nodoc:
126
- includee.before_create :expire_current_active
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.current.find( :first, :conditions => conditions )
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
@@ -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
- @instance = User.new( :name => 'John Smith', :effective_at => (DateTime.now - 1.days), :expiring_at => DateTime.end_of )
16
- @instance.save!
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.new( :number => '012345678901', :location => 'home', :effective_at => (DateTime.now - 1.days) )
34
- @instance.save!
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.new( :number => '019876543210', :location => 'home', :effective_at => DateTime.now )
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(:each) do
49
+ before :each do
50
50
  @klass = Address
51
- @instance = @klass.new( :street => '26 street', :location => 'home', :effective_at => (DateTime.now - 1.days) )
52
- @instance.save!
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.new( :street => '27 street', :location => 'home', :effective_at => DateTime.now )
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
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{transient}
8
- s.version = "1.0.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-27}
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.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-27 00:00:00 -06:00
12
+ date: 2009-12-29 00:00:00 -06:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency