genki-dm-has-versions 0.0.2 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -5,7 +5,7 @@ require 'merb-core'
5
5
  require 'merb-core/tasks/merb'
6
6
 
7
7
  GEM_NAME = "dm-has-versions"
8
- GEM_VERSION = "0.0.2"
8
+ GEM_VERSION = "0.1.0"
9
9
  AUTHOR = "Genki Takiuchi"
10
10
  EMAIL = "genki@s21g.com"
11
11
  HOMEPAGE = "http://blog.s21g.com/genki"
@@ -8,7 +8,7 @@ if defined?(Merb::Plugins)
8
8
 
9
9
  Merb::BootLoader.before_app_loads do
10
10
  # require code that must be loaded before the application
11
- require 'dm-has-version/has/versions'
11
+ require 'dm-has-versions/has/versions'
12
12
  DataMapper::Model.append_extensions DataMapper::Has::Versions
13
13
  end
14
14
 
@@ -1,6 +1,8 @@
1
1
  module DataMapper
2
2
  module Has
3
3
  module Versions
4
+ class RevertError < StandardError; end
5
+
4
6
  def has_versions(options = {})
5
7
  ignores = [options[:ignore]].flatten.compact.map do |ignore|
6
8
  properties[ignore.to_s.intern]
@@ -38,13 +40,18 @@ module DataMapper
38
40
  end
39
41
 
40
42
  self.after :update do |result|
41
- if result && dirty_attributes.except(*ignores).present?
42
- return result if pending_version_attributes.empty?
43
+ if result && !dirty_attributes.except(*ignores).empty?
44
+ break result if pending_version_attributes.empty?
43
45
  attributes = self.attributes.merge(pending_version_attributes)
44
46
  original_key = "#{self.class.storage_name.singular}_id"
45
47
  attributes[original_key.intern] = self.id
46
- self.class::Version.create(attributes.except(:id))
48
+ version, latest = self.version, self.latest?
49
+ transaction do
50
+ self.revert_to!(version) unless latest
51
+ self.class::Version.create(attributes.except(:id))
52
+ end
47
53
  self.pending_version_attributes.clear
54
+ @version = nil
48
55
  end
49
56
 
50
57
  result
@@ -78,25 +85,44 @@ module DataMapper
78
85
  version.all(original_key => self.id, :order => [:id.asc])
79
86
  end
80
87
 
88
+ def latest?
89
+ version == versions.size
90
+ end
91
+
81
92
  def version
82
- versions.size
93
+ @version ||= versions.size
83
94
  end
84
95
 
85
- def revert_to(version)
96
+ def version=(version)
86
97
  if target = versions.first(:offset => version)
87
- transaction do
88
- self.properties.each do |property|
89
- next if property.key?
90
- name = property.name
91
- self.attribute_set(name, target.attribute_get(name))
92
- end
93
- pending_version_attributes.clear
94
- return false unless save
95
- versions.all(:id.gte => target.id).destroy!
98
+ self.properties.each do |property|
99
+ next if property.key?
100
+ name = property.name
101
+ self.attribute_set(name, target.attribute_get(name))
96
102
  end
103
+ @version = version
97
104
  end
98
105
  !!target
99
106
  end
107
+
108
+ def revert_to!(version)
109
+ self.version = version
110
+ pending_version_attributes.clear
111
+ raise RevertError unless save
112
+ target_id = versions[version].id
113
+ versions.all(:id.gte => target_id).destroy!
114
+ end
115
+
116
+ def revert_to(version)
117
+ transaction{revert_to!(version)}
118
+ true
119
+ rescue RevertError
120
+ false
121
+ end
122
+
123
+ def revert
124
+ revert_to(version) or raise RevertError
125
+ end
100
126
  end
101
127
  end
102
128
  end
@@ -67,6 +67,25 @@ describe "dm-has-versions" do
67
67
  @story.version.should == 0
68
68
  @story.title.should == "test-1"
69
69
  end
70
+
71
+ it "should be set version" do
72
+ @story.title.should == "test-4"
73
+ @story.version.should == 3
74
+ @story.dirty_attributes[Story.title].should be_nil
75
+ @story.version = 1
76
+ @story.version.should == 1
77
+ @story.title.should == "test-2"
78
+ @story.dirty_attributes[Story.title].should_not be_nil
79
+ end
80
+
81
+ it "should revert to current version" do
82
+ @story.version = 1
83
+ @story.should_not be_latest
84
+ @story.save
85
+ @story.should be_latest
86
+ @story.title.should == "test-2"
87
+ @story.dirty_attributes[Story.title].should be_nil
88
+ end
70
89
  end
71
90
  end
72
91
  end
@@ -5,5 +5,6 @@ class Story
5
5
  property :title, String
6
6
  property :updated_at, DateTime
7
7
 
8
+ has n, :comments
8
9
  has_versions :ignore => [:updated_at]
9
10
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: genki-dm-has-versions
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Genki Takiuchi
@@ -45,6 +45,7 @@ files:
45
45
  - spec/fixture
46
46
  - spec/fixture/app
47
47
  - spec/fixture/app/models
48
+ - spec/fixture/app/models/comment.rb
48
49
  - spec/fixture/app/models/story.rb
49
50
  - spec/merb_test.log
50
51
  - spec/spec_helper.rb