activerecord-diff 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in ..gemspec
4
+ gemspec
data/README.txt ADDED
@@ -0,0 +1,42 @@
1
+ Simple ActiveRecord diff functionality.
2
+
3
+ Example usage:
4
+
5
+ require 'active_record/diff'
6
+
7
+ class User < ActiveRecord::Base
8
+ include ActiveRecord::Diff
9
+ end
10
+
11
+ alice = User.create(:name => 'alice', :email_address => 'alice@example.org')
12
+
13
+ bob = User.create(:name => 'bob', :email_address => 'bob@example.org')
14
+
15
+ alice.diff?(bob) # => true
16
+
17
+ alice.diff(bob) # => {:name => ['alice', 'bob'], :email_address => ['alice@example.org', 'bob@example.org']}
18
+
19
+ alice.diff({:name => 'eve'}) # => {:name => ['alice', 'eve']}
20
+
21
+
22
+ By default, ActiveRecord::Base.content_columns is used to decide which attributes
23
+ to compare. You can include or exclude attributes from this as follows:
24
+
25
+ class User < ActiveRecord::Base
26
+ diff :include => [:id], :exclude => [:password_hash]
27
+ end
28
+
29
+
30
+ Alternatively, you can specify exactly which columns to compare:
31
+
32
+ class User < ActiveRecord::Base
33
+ diff :id, :name, :email_address
34
+ end
35
+
36
+
37
+ This is an updated version of the "riff" rails plugin.
38
+
39
+
40
+ To the extent possible under law, Tim Fletcher has waived all copyright and
41
+ related or neighboring rights to activerecord-diff. This work is published
42
+ from the United Kingdom. http://creativecommons.org/publicdomain/zero/1.0/
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ require 'bundler'
2
+ require 'rake/testtask'
3
+
4
+ Bundler::GemHelper.install_tasks
5
+
6
+ Rake::TestTask.new do |t|
7
+ t.libs << "test"
8
+ t.test_files = FileList['test/test*.rb']
9
+ t.verbose = true
10
+ end
11
+
@@ -0,0 +1,28 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "active_record_diff/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "activerecord-diff"
7
+ s.version = ActiveRecordDiff::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Stephen Prater"]
10
+ s.email = ["stephenp@agrussell.com"]
11
+ s.homepage = "http://github.com/agrussellknives/activerecord-diff"
12
+ s.summary = %q{Gemify Simple diff for ActiveRecord objects.}
13
+ s.description = %q{Simple diff for ActiveRecord }
14
+
15
+ s.rubyforge_project = "activerecord-diff"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+
22
+ s.add_dependency('activerecord')
23
+ s.add_dependency('activesupport')
24
+
25
+ s.add_development_dependency('bundler')
26
+ s.add_development_dependency('rake')
27
+ s.add_development_dependency('sqlite3-ruby')
28
+ end
data/lib/..rb ADDED
@@ -0,0 +1,3 @@
1
+ module .
2
+ # Your code goes here...
3
+ end
@@ -0,0 +1,3 @@
1
+ module ActiveRecordDiff
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,64 @@
1
+ require 'active_support/core_ext'
2
+ require 'active_record'
3
+
4
+ module ActiveRecord
5
+ module Diff
6
+ module ClassMethods
7
+ def diff(*attrs)
8
+ write_inheritable_attribute(:diff_attrs, attrs)
9
+ end
10
+
11
+ def diff_attrs
12
+ attrs = read_inheritable_attribute(:diff_attrs)
13
+
14
+ if attrs.nil?
15
+ content_columns.map { |column| column.name }
16
+ elsif attrs.length == 1 && Hash === attrs.first
17
+ columns = content_columns.map { |column| column.name.to_sym }
18
+
19
+ columns + (attrs.first[:include] || []) - (attrs.first[:exclude] || [])
20
+ else
21
+ attrs
22
+ end
23
+ end
24
+ end
25
+
26
+ def self.included(base)
27
+ base.extend ClassMethods
28
+ end
29
+
30
+ def diff?(record = nil)
31
+ not diff(record).empty?
32
+ end
33
+
34
+ def diff(other_record = nil)
35
+ if other_record.nil?
36
+ old_record, new_record = self.class.find(id), self
37
+ else
38
+ old_record, new_record = self, other_record
39
+ end
40
+
41
+ if new_record.is_a?(Hash)
42
+ diff_each(new_record) do |(attr_name, hash_value)|
43
+ [attr_name, old_record.send(attr_name), hash_value]
44
+ end
45
+ else
46
+ diff_each(self.class.diff_attrs) do |attr_name|
47
+ [attr_name, old_record.send(attr_name), new_record.send(attr_name)]
48
+ end
49
+ end
50
+ end
51
+
52
+ def diff_each(enum)
53
+ enum.inject({}) do |diff_hash, attr_name|
54
+ attr_name, old_value, new_value = *yield(attr_name)
55
+
56
+ unless old_value === new_value
57
+ diff_hash[attr_name.to_sym] = [old_value, new_value]
58
+ end
59
+
60
+ diff_hash
61
+ end
62
+ end
63
+ end
64
+ end
data/test/test.rb ADDED
@@ -0,0 +1,77 @@
1
+ require 'activerecord-diff'
2
+ require 'test/unit'
3
+
4
+ require 'pry'
5
+
6
+ class Person < ActiveRecord::Base
7
+ include ActiveRecord::Diff
8
+ end
9
+
10
+ ActiveRecord::Base.establish_connection('adapter' => 'sqlite3', 'database' => ':memory:')
11
+
12
+ ActiveRecord::Schema.define do
13
+ create_table :people do |table|
14
+ table.column :name, :string
15
+ table.column :email_address, :string
16
+ end
17
+ end
18
+
19
+ Person.create :name => 'alice', :email_address => 'alice@example.org'
20
+
21
+ Person.create :name => 'bob', :email_address => 'bob@example.org'
22
+
23
+ Person.create :name => 'eve', :email_address => 'bob@example.org'
24
+
25
+ class TestCase < Test::Unit::TestCase
26
+ def setup
27
+ @people = Person.find(:all)
28
+
29
+ @alice, @bob, @eve = *@people
30
+ end
31
+
32
+ def keysort(hash)
33
+ hash.sort_by { |k, v| k.to_s }
34
+ end
35
+
36
+ def assert_diff(a, b, diff)
37
+ assert_equal keysort(diff), keysort(a.diff(b))
38
+ end
39
+
40
+ def test_diff_query
41
+ @people.each do |person|
42
+ @people.each do |other_person|
43
+ if other_person == person
44
+ assert_equal false, person.diff?(other_person)
45
+ else
46
+ assert person.diff?(other_person)
47
+ end
48
+ end
49
+ end
50
+ end
51
+
52
+ def test_diff_against_other_record
53
+ assert_diff @bob, @alice, {:name => %w( bob alice ), :email_address => %w( bob@example.org alice@example.org )}
54
+
55
+ assert_diff @bob, @eve, {:name => %w( bob eve )}
56
+ end
57
+
58
+ def test_diff_against_saved_self
59
+ assert ! @eve.diff?
60
+
61
+ @eve.name = 'alice'
62
+
63
+ assert @eve.diff?
64
+
65
+ assert_diff @eve, nil, {:name => ['eve', 'alice']}
66
+ end
67
+
68
+ def test_diff_against_hash
69
+ assert_diff @bob, {:name => 'joe'}, {:name => ['bob', 'joe']}
70
+ end
71
+
72
+ def test_inclusion_and_exclusion
73
+ Person.diff :include => [:id], :exclude => [:email_address]
74
+
75
+ assert_diff @alice, @bob, {:id => [1, 2], :name => %w( alice bob )}
76
+ end
77
+ end
metadata ADDED
@@ -0,0 +1,112 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: activerecord-diff
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Stephen Prater
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-10-13 00:00:00.000000000 -05:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: activerecord
17
+ requirement: &10351960 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: *10351960
26
+ - !ruby/object:Gem::Dependency
27
+ name: activesupport
28
+ requirement: &10351750 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: *10351750
37
+ - !ruby/object:Gem::Dependency
38
+ name: bundler
39
+ requirement: &10351540 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ! '>='
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ type: :development
46
+ prerelease: false
47
+ version_requirements: *10351540
48
+ - !ruby/object:Gem::Dependency
49
+ name: rake
50
+ requirement: &10351330 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ type: :development
57
+ prerelease: false
58
+ version_requirements: *10351330
59
+ - !ruby/object:Gem::Dependency
60
+ name: sqlite3-ruby
61
+ requirement: &10351120 !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ! '>='
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ type: :development
68
+ prerelease: false
69
+ version_requirements: *10351120
70
+ description: ! 'Simple diff for ActiveRecord '
71
+ email:
72
+ - stephenp@agrussell.com
73
+ executables: []
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - .gitignore
78
+ - Gemfile
79
+ - README.txt
80
+ - Rakefile
81
+ - activerecord-diff.gemspec
82
+ - lib/..rb
83
+ - lib/active_record_diff/version.rb
84
+ - lib/activerecord-diff.rb
85
+ - test/test.rb
86
+ has_rdoc: true
87
+ homepage: http://github.com/agrussellknives/activerecord-diff
88
+ licenses: []
89
+ post_install_message:
90
+ rdoc_options: []
91
+ require_paths:
92
+ - lib
93
+ required_ruby_version: !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ required_rubygems_version: !ruby/object:Gem::Requirement
100
+ none: false
101
+ requirements:
102
+ - - ! '>='
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ requirements: []
106
+ rubyforge_project: activerecord-diff
107
+ rubygems_version: 1.5.2
108
+ signing_key:
109
+ specification_version: 3
110
+ summary: Gemify Simple diff for ActiveRecord objects.
111
+ test_files:
112
+ - test/test.rb