laserlemon-vestal_versions 0.3.0 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -2,7 +2,7 @@ require 'rubygems'
2
2
  require 'rake'
3
3
  require 'echoe'
4
4
 
5
- Echoe.new('vestal_versions', '0.3.0') do |g|
5
+ Echoe.new('vestal_versions', '0.4.1') do |g|
6
6
  g.description = %(Keep a DRY history of your ActiveRecord models' changes)
7
7
  g.url = 'http://github.com/laserlemon/vestal_versions'
8
8
  g.author = 'Steve Richert'
data/VERSION.yml CHANGED
@@ -1,4 +1,4 @@
1
1
  ---
2
2
  :major: 0
3
- :minor: 3
4
- :patch: 0
3
+ :minor: 4
4
+ :patch: 1
data/lib/version.rb CHANGED
@@ -2,17 +2,9 @@ class Version < ActiveRecord::Base
2
2
 
3
3
  belongs_to :versioned, :polymorphic => true
4
4
 
5
- validates_presence_of :versioned, :changes, :number
6
- validates_numericality_of :number, :greater_than => 0, :only_integer => true
7
- validates_uniqueness_of :number, :scope => ['versioned_type', 'versioned_id']
8
-
9
5
  serialize :changes, Hash
10
6
 
11
- before_create :set_number
12
-
13
- def version
14
- number
15
- end
7
+ alias_attribute :version, :number
16
8
 
17
9
  def <=>(other)
18
10
  number <=> other.number
@@ -25,10 +17,4 @@ class Version < ActiveRecord::Base
25
17
  def >(other)
26
18
  number > other.number
27
19
  end
28
-
29
- private
30
-
31
- def set_number
32
- write_attribute(:number, versioned.version.to_i + 1)
33
- end
34
20
  end
@@ -8,54 +8,62 @@ module LaserLemon
8
8
 
9
9
  module ClassMethods
10
10
  def versioned
11
- has_many :versions, :as => :versioned, :order => 'versions.number', :dependent => :destroy, :autosave => true do
12
- def current
13
- first(:conditions => {:number => versioned.version})
14
- end
15
-
11
+ has_many :versions, :as => :versioned, :order => 'versions.number ASC', :dependent => :destroy do
16
12
  def at(value)
17
13
  case value
18
14
  when Version: value
19
- when Symbol: send(value)
20
- when Numeric: first(:conditions => {:number => value.floor})
21
- when Date, Time: last(:conditions => ['versions.created_at <= ?', value.to_time])
15
+ when Numeric: find_by_number(value.floor)
16
+ when Symbol: respond_to?(value) ? send(value) : nil
17
+ when Date, Time: last(:conditions => ['versions.created_at <= ?', value.to_time.in_time_zone])
22
18
  end
23
19
  end
24
20
 
25
21
  def between(from_value, to_value)
26
- from, to = at(from_value), at(to_value)
27
- return [] unless [from, to].all?{|v| v.is_a?(Version) }
22
+ from, to = number_at(from_value), number_at(to_value)
23
+ return [] if from.nil? || to.nil? || (from == to)
28
24
  all(
29
- :conditions => {:number => ([from, to].min.number..[from, to].max.number)},
25
+ :conditions => {:number => Range.new(*[from, to].sort)},
30
26
  :order => "versions.number #{(from > to) ? 'DESC' : 'ASC'}"
31
27
  )
32
28
  end
29
+
30
+ private
31
+
32
+ def number_at(value)
33
+ case value
34
+ when Version: value.number
35
+ when Numeric: value.floor
36
+ when Symbol, Date, Time: at(value).try(:number)
37
+ end
38
+ end
33
39
  end
34
40
 
35
- before_save :build_version
41
+ after_save :create_version, :if => :needs_version?
36
42
 
37
43
  include InstanceMethods
38
44
  end
39
45
  end
40
46
 
41
47
  module InstanceMethods
42
- def build_version
43
- @version = nil
44
- versions.reload
45
- unless changes.blank?
46
- if versions.empty?
47
- if new_record?
48
- versions.build(:changes => attributes)
49
- else
50
- reverted_attributes = attributes.inject({}){|h,(k,v)| h.update(k => (changed.include?(k) ? changes[k].first : v)) }
51
- version_timestamp = (try(:updated_at) || try(:created_at))
52
- versions.build(:changes => reverted_attributes, :created_at => version_timestamp)
53
- end
54
- end
55
- versions.build(:changes => changes) unless new_record?
48
+ private
49
+
50
+ def needs_version?
51
+ !changed.empty?
52
+ end
53
+
54
+ def create_version
55
+ if versions.empty?
56
+ versions.create(:changes => attributes, :number => 1)
57
+ else
58
+ @version = nil
59
+ versions.create(:changes => changes, :number => (version.to_i + 1))
56
60
  end
61
+
62
+ @version = nil
57
63
  end
58
64
 
65
+ public
66
+
59
67
  def version
60
68
  @version ||= versions.maximum(:number)
61
69
  end
@@ -63,13 +71,16 @@ module LaserLemon
63
71
  def revert_to(value)
64
72
  chain = versions.between(version, value)
65
73
  return version unless chain.size > 1
74
+
66
75
  new_version, backward = chain.last.number, (chain.first > chain.last)
67
76
  backward ? chain.pop : chain.shift
77
+
68
78
  chain.each do |version|
69
- version.changes.each do |attribute, change|
79
+ version.changes.except('updated_at', 'updated_on').each do |attribute, change|
70
80
  write_attribute(attribute, backward ? change.first : change.last)
71
81
  end
72
82
  end
83
+
73
84
  @version = new_version
74
85
  end
75
86
 
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{vestal_versions}
5
- s.version = "0.3.0"
5
+ s.version = "0.4.1"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Steve Richert"]
9
- s.date = %q{2009-08-11}
9
+ s.date = %q{2009-08-12}
10
10
  s.description = %q{Keep a DRY history of your ActiveRecord models' changes}
11
11
  s.email = %q{steve@laserlemon.com}
12
12
  s.extra_rdoc_files = ["lib/version.rb", "lib/vestal_versions.rb", "README.rdoc", "tasks/vestal_versions_tasks.rake"]
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: laserlemon-vestal_versions
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steve Richert
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-08-11 00:00:00 -07:00
12
+ date: 2009-08-12 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies: []
15
15