paper_trail 1.6.4 → 1.6.5

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/README.md CHANGED
@@ -541,6 +541,7 @@ Many thanks to:
541
541
  * Danny Trelogan
542
542
  * [Mikl Kurkov](http://github.com/mkurkov)
543
543
  * [Franco Catena](https://github.com/francocatena)
544
+ * [Emmanuel](https://github.com/emmanuel)
544
545
 
545
546
 
546
547
  ## Inspirations
@@ -3,9 +3,6 @@ module PaperTrail
3
3
 
4
4
  def self.included(base)
5
5
  base.send :extend, ClassMethods
6
-
7
- # The version this instance was reified from.
8
- attr_accessor :version
9
6
  end
10
7
 
11
8
 
@@ -24,6 +21,9 @@ module PaperTrail
24
21
  # any more ActiveRecord models than we have to.
25
22
  send :include, InstanceMethods
26
23
 
24
+ # The version this instance was reified from.
25
+ attr_accessor :version
26
+
27
27
  cattr_accessor :ignore
28
28
  self.ignore = (options[:ignore] || []).map &:to_s
29
29
 
@@ -71,14 +71,14 @@ module PaperTrail
71
71
  def version_at(timestamp)
72
72
  # Because a version stores how its object looked *before* the change,
73
73
  # we need to look for the first version created *after* the timestamp.
74
- version = versions.first :conditions => ['created_at > ?', timestamp], :order => 'created_at ASC, id ASC'
74
+ version = versions.after(timestamp).first
75
75
  version ? version.reify : self
76
76
  end
77
77
 
78
78
  # Returns the object (not a Version) as it was most recently.
79
79
  def previous_version
80
- last_version = version ? version.previous : versions.last
81
- last_version.try :reify
80
+ preceding_version = version ? version.previous : versions.last
81
+ preceding_version.try :reify
82
82
  end
83
83
 
84
84
  # Returns the object (not a Version) as it became next.
@@ -98,7 +98,7 @@ module PaperTrail
98
98
  end
99
99
 
100
100
  def record_update
101
- if switched_on? && changed_and_we_care?
101
+ if switched_on? && changed_notably?
102
102
  versions.build merge_metadata(:event => 'update',
103
103
  :object => object_to_string(item_before_change),
104
104
  :whodunnit => PaperTrail.whodunnit)
@@ -117,27 +117,36 @@ module PaperTrail
117
117
  def merge_metadata(data)
118
118
  # First we merge the model-level metadata in `meta`.
119
119
  meta.each do |k,v|
120
- data[k] = v.respond_to?(:call) ? v.call(self) : v
120
+ data[k] =
121
+ if v.respond_to?(:call)
122
+ v.call(self)
123
+ elsif v.is_a?(Symbol) && respond_to?(v)
124
+ send(v)
125
+ else
126
+ v
127
+ end
121
128
  end
122
129
  # Second we merge any extra data from the controller (if available).
123
130
  data.merge(PaperTrail.controller_info || {})
124
131
  end
125
132
 
126
133
  def item_before_change
127
- previous = self.clone
128
- previous.id = id
129
- changes.each do |attr, ary|
130
- previous.send :write_attribute, attr.to_sym, ary.first
134
+ self.clone.tap do |previous|
135
+ previous.id = id
136
+ changed_attributes.each { |attr, before| previous[attr] = before }
131
137
  end
132
- previous
133
138
  end
134
139
 
135
140
  def object_to_string(object)
136
141
  object.attributes.to_yaml
137
142
  end
138
143
 
139
- def changed_and_we_care?
140
- changed? and !(changed - self.class.ignore).empty?
144
+ def changed_notably?
145
+ notably_changed.any?
146
+ end
147
+
148
+ def notably_changed
149
+ changed - self.class.ignore
141
150
  end
142
151
 
143
152
  # Returns `true` if PaperTrail is globally enabled and active for this class,
@@ -2,6 +2,26 @@ class Version < ActiveRecord::Base
2
2
  belongs_to :item, :polymorphic => true
3
3
  validates_presence_of :event
4
4
 
5
+ named_scope :with_item_keys, lambda { |item_type, item_id| {
6
+ :conditions => { :item_type => item_type, :item_id => item_id }
7
+ } }
8
+
9
+ named_scope :subsequent, lambda { |version| {
10
+ :conditions => ["id > ?", version.is_a?(ActiveRecord::Base) ? version.id : version],
11
+ :order => "id ASC",
12
+ } }
13
+
14
+ named_scope :preceding, lambda { |version| {
15
+ :conditions => ["id < ?", version.is_a?(ActiveRecord::Base) ? version.id : version],
16
+ :order => "id DESC",
17
+ } }
18
+
19
+ named_scope :after, lambda { |timestamp| {
20
+ :conditions => ['created_at > ?', timestamp],
21
+ # TODO: is this :order necessary, considering its presence on the has_many :versions association?
22
+ :order => 'created_at ASC, id ASC'
23
+ } }
24
+
5
25
  # Restore the item from this version.
6
26
  #
7
27
  # This will automatically restore all :has_one associations as they were "at the time",
@@ -69,19 +89,20 @@ class Version < ActiveRecord::Base
69
89
  whodunnit
70
90
  end
71
91
 
92
+ def sibling_versions
93
+ Version.with_item_keys(item_type, item_id)
94
+ end
95
+
72
96
  def next
73
- Version.first :conditions => ["id > ? AND item_type = ? AND item_id = ?", id, item_type, item_id],
74
- :order => 'id ASC'
97
+ sibling_versions.subsequent(self).first
75
98
  end
76
99
 
77
100
  def previous
78
- Version.first :conditions => ["id < ? AND item_type = ? AND item_id = ?", id, item_type, item_id],
79
- :order => 'id DESC'
101
+ sibling_versions.preceding(self).first
80
102
  end
81
103
 
82
104
  def index
83
- Version.all(:conditions => ["item_type = ? AND item_id = ?", item_type, item_id],
84
- :order => 'id ASC').index(self)
105
+ sibling_versions.all(:select => :id, :order => "id ASC").map(&:id).index(self.id)
85
106
  end
86
107
 
87
108
  private
@@ -1,3 +1,3 @@
1
1
  module PaperTrail
2
- VERSION = '1.6.4'
2
+ VERSION = '1.6.5'
3
3
  end
data/paper_trail.gemspec CHANGED
@@ -21,7 +21,10 @@ Gem::Specification.new do |s|
21
21
  s.add_development_dependency 'shoulda', '2.10.3'
22
22
  s.add_development_dependency 'activesupport', '~> 2.3'
23
23
  s.add_development_dependency 'sqlite3-ruby', '~> 1.2'
24
+ # Repeated here to make bundler happy
25
+ s.add_development_dependency 'activerecord', '~> 2.3'
26
+ s.add_development_dependency 'actionpack', '~> 2.3'
24
27
 
25
- s.add_dependency 'activerecord', '>= 2.3'
26
- s.add_dependency 'actionpack', '>= 2.3'
28
+ s.add_dependency 'activerecord', '~> 2.3'
29
+ s.add_dependency 'actionpack', '~> 2.3'
27
30
  end
@@ -21,8 +21,13 @@ end
21
21
  class Article < ActiveRecord::Base
22
22
  has_paper_trail :ignore => [:title],
23
23
  :meta => {:answer => 42,
24
+ :action => :action_data_provider_method,
24
25
  :question => Proc.new { "31 + 11 = #{31 + 11}" },
25
26
  :article_id => Proc.new { |article| article.id } }
27
+
28
+ def action_data_provider_method
29
+ self.object_id.to_s
30
+ end
26
31
  end
27
32
 
28
33
  class Book < ActiveRecord::Base
@@ -528,6 +533,10 @@ class HasPaperTrailModelTest < Test::Unit::TestCase
528
533
  assert_equal @article.id, @article.versions.last.article_id
529
534
  end
530
535
 
536
+ should 'store dynamic meta data based on a method of the item' do
537
+ assert_equal @article.action_data_provider_method, @article.versions.last.action
538
+ end
539
+
531
540
 
532
541
  context 'and updated' do
533
542
  setup { @article.update_attributes! :content => 'Better text.' }
data/test/schema.rb CHANGED
@@ -25,6 +25,7 @@ ActiveRecord::Schema.define(:version => 0) do
25
25
 
26
26
  # Metadata columns.
27
27
  t.integer :answer
28
+ t.string :action
28
29
  t.string :question
29
30
  t.integer :article_id
30
31
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: paper_trail
3
3
  version: !ruby/object:Gem::Version
4
- hash: 7
4
+ hash: 5
5
5
  prerelease: false
6
6
  segments:
7
7
  - 1
8
8
  - 6
9
- - 4
10
- version: 1.6.4
9
+ - 5
10
+ version: 1.6.5
11
11
  platform: ruby
12
12
  authors:
13
13
  - Andy Stewart
@@ -15,14 +15,13 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-11-19 00:00:00 +00:00
18
+ date: 2011-02-08 00:00:00 +00:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
22
  name: bundler
23
- type: :development
24
23
  prerelease: false
25
- version_requirements: &id001 !ruby/object:Gem::Requirement
24
+ requirement: &id001 !ruby/object:Gem::Requirement
26
25
  none: false
27
26
  requirements:
28
27
  - - ~>
@@ -32,12 +31,12 @@ dependencies:
32
31
  - 1
33
32
  - 0
34
33
  version: "1.0"
35
- requirement: *id001
34
+ type: :development
35
+ version_requirements: *id001
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rake
38
- type: :development
39
38
  prerelease: false
40
- version_requirements: &id002 !ruby/object:Gem::Requirement
39
+ requirement: &id002 !ruby/object:Gem::Requirement
41
40
  none: false
42
41
  requirements:
43
42
  - - "="
@@ -48,12 +47,12 @@ dependencies:
48
47
  - 8
49
48
  - 7
50
49
  version: 0.8.7
51
- requirement: *id002
50
+ type: :development
51
+ version_requirements: *id002
52
52
  - !ruby/object:Gem::Dependency
53
53
  name: shoulda
54
- type: :development
55
54
  prerelease: false
56
- version_requirements: &id003 !ruby/object:Gem::Requirement
55
+ requirement: &id003 !ruby/object:Gem::Requirement
57
56
  none: false
58
57
  requirements:
59
58
  - - "="
@@ -64,12 +63,12 @@ dependencies:
64
63
  - 10
65
64
  - 3
66
65
  version: 2.10.3
67
- requirement: *id003
66
+ type: :development
67
+ version_requirements: *id003
68
68
  - !ruby/object:Gem::Dependency
69
69
  name: activesupport
70
- type: :development
71
70
  prerelease: false
72
- version_requirements: &id004 !ruby/object:Gem::Requirement
71
+ requirement: &id004 !ruby/object:Gem::Requirement
73
72
  none: false
74
73
  requirements:
75
74
  - - ~>
@@ -79,12 +78,12 @@ dependencies:
79
78
  - 2
80
79
  - 3
81
80
  version: "2.3"
82
- requirement: *id004
81
+ type: :development
82
+ version_requirements: *id004
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: sqlite3-ruby
85
- type: :development
86
85
  prerelease: false
87
- version_requirements: &id005 !ruby/object:Gem::Requirement
86
+ requirement: &id005 !ruby/object:Gem::Requirement
88
87
  none: false
89
88
  requirements:
90
89
  - - ~>
@@ -94,37 +93,68 @@ dependencies:
94
93
  - 1
95
94
  - 2
96
95
  version: "1.2"
97
- requirement: *id005
96
+ type: :development
97
+ version_requirements: *id005
98
98
  - !ruby/object:Gem::Dependency
99
99
  name: activerecord
100
- type: :runtime
101
100
  prerelease: false
102
- version_requirements: &id006 !ruby/object:Gem::Requirement
101
+ requirement: &id006 !ruby/object:Gem::Requirement
103
102
  none: false
104
103
  requirements:
105
- - - ">="
104
+ - - ~>
106
105
  - !ruby/object:Gem::Version
107
106
  hash: 5
108
107
  segments:
109
108
  - 2
110
109
  - 3
111
110
  version: "2.3"
112
- requirement: *id006
111
+ type: :development
112
+ version_requirements: *id006
113
113
  - !ruby/object:Gem::Dependency
114
114
  name: actionpack
115
+ prerelease: false
116
+ requirement: &id007 !ruby/object:Gem::Requirement
117
+ none: false
118
+ requirements:
119
+ - - ~>
120
+ - !ruby/object:Gem::Version
121
+ hash: 5
122
+ segments:
123
+ - 2
124
+ - 3
125
+ version: "2.3"
126
+ type: :development
127
+ version_requirements: *id007
128
+ - !ruby/object:Gem::Dependency
129
+ name: activerecord
130
+ prerelease: false
131
+ requirement: &id008 !ruby/object:Gem::Requirement
132
+ none: false
133
+ requirements:
134
+ - - ~>
135
+ - !ruby/object:Gem::Version
136
+ hash: 5
137
+ segments:
138
+ - 2
139
+ - 3
140
+ version: "2.3"
115
141
  type: :runtime
142
+ version_requirements: *id008
143
+ - !ruby/object:Gem::Dependency
144
+ name: actionpack
116
145
  prerelease: false
117
- version_requirements: &id007 !ruby/object:Gem::Requirement
146
+ requirement: &id009 !ruby/object:Gem::Requirement
118
147
  none: false
119
148
  requirements:
120
- - - ">="
149
+ - - ~>
121
150
  - !ruby/object:Gem::Version
122
151
  hash: 5
123
152
  segments:
124
153
  - 2
125
154
  - 3
126
155
  version: "2.3"
127
- requirement: *id007
156
+ type: :runtime
157
+ version_requirements: *id009
128
158
  description: Track changes to your models' data. Good for auditing or versioning.
129
159
  email: boss@airbladesoftware.com
130
160
  executables: []