paper_trail_changes 0.0.0 → 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -2,6 +2,7 @@ source "http://rubygems.org"
2
2
  # Add dependencies required to use your gem here.
3
3
  # Example:
4
4
  # gem "activesupport", ">= 2.3.5"
5
+ gem "string-cases"
5
6
 
6
7
  # Add dependencies to develop your gem here.
7
8
  # Include everything needed to run rake, tests, features, etc.
data/Gemfile.lock CHANGED
@@ -52,6 +52,7 @@ GEM
52
52
  rspec-expectations (2.8.0)
53
53
  diff-lcs (~> 1.1.2)
54
54
  rspec-mocks (2.8.0)
55
+ string-cases (0.0.0)
55
56
 
56
57
  PLATFORMS
57
58
  ruby
@@ -61,3 +62,4 @@ DEPENDENCIES
61
62
  jeweler (~> 1.8.4)
62
63
  rdoc (~> 3.12)
63
64
  rspec (~> 2.8.0)
65
+ string-cases
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.0
1
+ 0.0.1
@@ -1,6 +1,98 @@
1
+ require "string-cases"
2
+
1
3
  class PaperTrailChanges
2
- def last_version(model)
4
+ def self.last_version(model)
3
5
  version = Version.where(:item_type => model.class.name, :item_id => model.id, :event => :update).order(:id).reverse_order.first
4
6
  return version
5
7
  end
8
+
9
+ CHANGES_SINCE_VERSION_VALID_ARGS = [:version_id, :version_at, :model, :attributes]
10
+ def self.changes_since_version(args)
11
+ args.each do |key, val|
12
+ raise "Invalid argument: '#{key}'." unless CHANGES_SINCE_VERSION_VALID_ARGS.include?(key)
13
+ end
14
+
15
+ attributes, model = args[:attributes], args[:model]
16
+
17
+ column_types = PaperTrailChanges.column_types_from_class(model.class)
18
+
19
+ if args[:version_id]
20
+ version_obj = Version.find(args[:version_id]) rescue nil
21
+ elsif args[:version_at]
22
+ version_model = model.version_at(args[:version_at])
23
+ end
24
+
25
+ version_model = model if version_obj.nil? && version_model.nil?
26
+
27
+ if version_obj
28
+ version_hash = Psych.load(version_obj.object).stringify_keys
29
+ elsif version_model
30
+ version_hash = {}
31
+ version_model.attributes.each do |key, val|
32
+ version_hash[key.to_s] = version_model.__send__("#{key}_before_type_cast")
33
+ end
34
+ else
35
+ raise "Dont know what to do?"
36
+ end
37
+
38
+ changes_since = PaperTrailChanges.changes_hash(
39
+ :attributes => attributes,
40
+ :version_hash => version_hash,
41
+ :model => model,
42
+ :column_types => column_types
43
+ )
44
+
45
+ return changes_since
46
+ end
47
+
48
+ def self.column_types_from_class(class_obj)
49
+ column_types = {}
50
+ class_obj.columns_hash.each do |name, col|
51
+ column_types[name] = col.type
52
+ end
53
+
54
+ return column_types
55
+ end
56
+
57
+ CHANGES_HASH_VALID_ARGS = [:attributes, :version_hash, :model, :column_types]
58
+ def self.changes_hash(args)
59
+ args.each do |key, val|
60
+ raise "Invalid argument: '#{key}'." unless CHANGES_HASH_VALID_ARGS.include?(key)
61
+ end
62
+
63
+ attributes, version_hash, model, column_types = args[:attributes], args[:version_hash], args[:model], args[:column_types]
64
+ changes_since = {}
65
+
66
+ attributes.each do |key, val|
67
+ key_s = key.to_s
68
+
69
+ if match = key_s.match(/^(.+)_attributes$/)
70
+ # Nested model. Since paper-trail doesn't keep track of this just pass it through.
71
+ changes_since[key] = val
72
+ elsif version_hash.key?(key_s)
73
+ last_val = version_hash[key_s]
74
+ changed = false
75
+ type = column_types[key_s]
76
+
77
+ if type == :string || type == :date || type == :text || type == :datetime
78
+ changed = true if last_val.to_s != val.to_s
79
+ elsif type == :integer
80
+ changed = true if last_val.to_i != val.to_i
81
+ changed = true if last_val == nil && val
82
+ elsif type == :boolean
83
+ bool_i = last_val ? 1 : 0
84
+ changed = true if bool_i != val.to_i
85
+ changed = true if last_val == nil && val
86
+ else
87
+ raise "Unknown type: '#{type}'."
88
+ end
89
+
90
+ changes_since[key_s] = val if changed
91
+ else
92
+ changes_since[key_s] = val
93
+ end
94
+ end
95
+
96
+ return changes_since
97
+ end
6
98
  end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "paper_trail_changes"
8
- s.version = "0.0.0"
8
+ s.version = "0.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 = ["kaspernj"]
12
- s.date = "2013-08-14"
12
+ s.date = "2013-08-15"
13
13
  s.description = "A gem to do various stuff with PaperTrail versions."
14
14
  s.email = "k@spernj.org"
15
15
  s.extra_rdoc_files = [
@@ -40,17 +40,20 @@ Gem::Specification.new do |s|
40
40
  s.specification_version = 3
41
41
 
42
42
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
43
+ s.add_runtime_dependency(%q<string-cases>, [">= 0"])
43
44
  s.add_development_dependency(%q<rspec>, ["~> 2.8.0"])
44
45
  s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
45
46
  s.add_development_dependency(%q<bundler>, [">= 1.0.0"])
46
47
  s.add_development_dependency(%q<jeweler>, ["~> 1.8.4"])
47
48
  else
49
+ s.add_dependency(%q<string-cases>, [">= 0"])
48
50
  s.add_dependency(%q<rspec>, ["~> 2.8.0"])
49
51
  s.add_dependency(%q<rdoc>, ["~> 3.12"])
50
52
  s.add_dependency(%q<bundler>, [">= 1.0.0"])
51
53
  s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
52
54
  end
53
55
  else
56
+ s.add_dependency(%q<string-cases>, [">= 0"])
54
57
  s.add_dependency(%q<rspec>, ["~> 2.8.0"])
55
58
  s.add_dependency(%q<rdoc>, ["~> 3.12"])
56
59
  s.add_dependency(%q<bundler>, [">= 1.0.0"])
@@ -1,5 +1,53 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
2
 
3
+ class Submodel
4
+ def columns_hash
5
+
6
+ end
7
+ end
8
+
3
9
  describe "PaperTrailChanges" do
10
+ it "should handle booleans" do
11
+ changes = PaperTrailChanges.changes_hash(
12
+ :attributes => {"works" => "1", "fails" => 0, "doesnt_fail" => "1"},
13
+ :version_hash => {"works" => true, "fails" => false, "doesnt_fail" => false},
14
+ :column_types => {"works" => :boolean, "fails" => :boolean, "doesnt_fail" => :boolean}
15
+ )
16
+
17
+ changes.length.should eql(1)
18
+ changes.keys.first.should eql("doesnt_fail")
19
+ changes.values.first.should eql("1")
20
+ end
21
+
22
+ it "should handle integers" do
23
+ changes = PaperTrailChanges.changes_hash(
24
+ :attributes => {"number1" => "1", "number2" => "2", "number3" => "3"},
25
+ :version_hash => {"number1" => 1, "number2" => 2, "number3" => 33},
26
+ :column_types => {"number1" => :integer, "number2" => :integer, "number3" => :integer}
27
+ )
28
+
29
+ changes.length.should eql(1)
30
+ changes.keys.first.should eql("number3")
31
+ changes.values.first.should eql("3")
32
+ end
33
+
34
+ it "should handle strings" do
35
+ changes = PaperTrailChanges.changes_hash(
36
+ :attributes => {"str1" => "123", "str2" => "234", "str3" => 3},
37
+ :version_hash => {"str1" => "1234", "str2" => "234", "str3" => 3},
38
+ :column_types => {"str1" => :string, "str2" => :text, "str3" => :string}
39
+ )
40
+
41
+ changes.length.should eql(1)
42
+ changes.keys.first.should eql("str1")
43
+ changes.values.first.should eql("123")
44
+ end
4
45
 
46
+ it "should handle nested attributes" do
47
+ changes = PaperTrailChanges.changes_hash(
48
+ :attributes => {"submodel_attributes" => {"test1" => "test1", "test2" => 2, "test3" => "changed"}},
49
+ :version_hash => {"submodel" => {"test1" => "test1", "test2" => 2, "test3" => "test3"}},
50
+ :column_types => {}
51
+ )
52
+ end
5
53
  end
metadata CHANGED
@@ -2,15 +2,31 @@
2
2
  name: paper_trail_changes
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.0.0
5
+ version: 0.0.1
6
6
  platform: ruby
7
7
  authors:
8
8
  - kaspernj
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-08-14 00:00:00.000000000 Z
12
+ date: 2013-08-15 00:00:00.000000000 Z
13
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ version_requirements: !ruby/object:Gem::Requirement
16
+ none: false
17
+ requirements:
18
+ - - ! '>='
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
21
+ name: string-cases
22
+ type: :runtime
23
+ prerelease: false
24
+ requirement: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
14
30
  - !ruby/object:Gem::Dependency
15
31
  version_requirements: !ruby/object:Gem::Requirement
16
32
  none: false
@@ -109,7 +125,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
109
125
  - !ruby/object:Gem::Version
110
126
  segments:
111
127
  - 0
112
- hash: -3618021520237963186
128
+ hash: -3375604828162703244
113
129
  version: '0'
114
130
  required_rubygems_version: !ruby/object:Gem::Requirement
115
131
  none: false