genki-dm-has-versions 0.0.2 → 0.1.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/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