trackit 0.1

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/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2012 YOURNAME
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,128 @@
1
+ TrackIt
2
+ =======
3
+
4
+ TrackIt is a small gem which helps you keep track of changes in you ActiveRecord models persistently.
5
+ While ActiveModel::Dirty allows you to keep track on changes only when the change occurs, TrackIt will keep attributes as changed until you decide to clear them.
6
+
7
+ Getting Started
8
+ ===============
9
+
10
+ First you will have to add TrackIt to your gemfile.
11
+
12
+ ```ruby
13
+ gem 'trackit'
14
+ ```
15
+
16
+ Run the `bundle install` command in order to install the gem.
17
+
18
+ After the gem was successfully installed you need to run the generator:
19
+
20
+ ```console
21
+ rails generate track_it Model attr_a attr_b
22
+ ```
23
+
24
+ This will generate tracking for Model class which inherits from ActiveRecord::Base, and only for attributes attr_a, attr_b.
25
+
26
+ The last step is migrating your database:
27
+
28
+ ```console
29
+ rake db:migrate
30
+ ```
31
+
32
+ You may need to restart your app if it is already running.
33
+
34
+ Usage
35
+ =====
36
+
37
+ TrackIt provides an interface on your model instance as follows:
38
+
39
+ ```ruby
40
+ model = Model.new
41
+
42
+ model.tracked.changed?
43
+ model.tracked.changed
44
+ model.tracked.attr_a_changed?
45
+ model.tracked.attr_b_changed?
46
+ .
47
+ .
48
+ .
49
+ ```
50
+
51
+ Each method corresponds to its similiar named method under [ActiveModel::Dirty](http://api.rubyonrails.org/classes/ActiveModel/Dirty.html).
52
+
53
+ Two auxiliary methods are supplied:
54
+
55
+ ```ruby
56
+ model.tracked.set_all_changed
57
+ model.tracked.set_all_unchanged
58
+ ```
59
+
60
+ Which sets all tracked attributes to changed/unchaged states.
61
+
62
+ Concrete Example
63
+ ================
64
+ Assume you have a User model which has the following attributes: name, address, current_job
65
+
66
+ ```ruby
67
+ class User < ActiveRecord::Base
68
+ end
69
+ ```
70
+
71
+ And you want to keep track on all those users who changed their current jobs or addresses:
72
+
73
+ ```console
74
+ rails generate track_it User address current_job
75
+ ```
76
+
77
+ And
78
+
79
+ ```console
80
+ rake db:migrate
81
+ ```
82
+
83
+ Let's take a look at the effects of our change:
84
+
85
+ ```ruby
86
+ u = User.create!(:name => "user1", :adderss => "address1", :current_job => "job1")
87
+
88
+ u.address = "address2"
89
+ u.current_job = "job2"
90
+
91
+ u.current_job_changed? # => true
92
+ u.address_changed? # => true
93
+ u.changed? # => true
94
+ u.changed # => ['address', 'current_job']
95
+
96
+ u.tracked.current_job_changed? # => false
97
+ u.tracked.address_changed? # => false
98
+ u.tracked.changed? # => false
99
+ u.tracked.changed # => []
100
+
101
+ u.save!
102
+
103
+ u.current_job_changed? # => false
104
+ u.address_changed? # => false
105
+ u.changed? # => false
106
+ u.changed # => []
107
+
108
+
109
+ u.tracked.current_job_changed? # => true
110
+ u.tracked.address_changed? # => true
111
+ u.tracked.changed? # => true
112
+ u.tracked.changed # => ['address', 'current_job']
113
+
114
+ u.tracked.set_unchanged(:current_job)
115
+ u.tracked.current_job_changed? # => false
116
+
117
+ u.tracked.set_changed(:current_job)
118
+ u.tracked.current_job_changed? # => true
119
+
120
+ u.tracked.set_all_unchanged
121
+ u.tracked.changed? # => false
122
+ u.tracked.changed # => []
123
+
124
+ u.tracked.set_all_changed
125
+ u.tracked.changed? # => true
126
+ u.tracked.changed # => ['address', 'current_job'] # note name is not changed - only tracked attributes get changed.
127
+
128
+ ```
data/Rakefile ADDED
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+ begin
8
+ require 'rdoc/task'
9
+ rescue LoadError
10
+ require 'rdoc/rdoc'
11
+ require 'rake/rdoctask'
12
+ RDoc::Task = Rake::RDocTask
13
+ end
14
+
15
+ RDoc::Task.new(:rdoc) do |rdoc|
16
+ rdoc.rdoc_dir = 'rdoc'
17
+ rdoc.title = 'TrackeIt'
18
+ rdoc.options << '--line-numbers'
19
+ rdoc.rdoc_files.include('README.rdoc')
20
+ rdoc.rdoc_files.include('lib/**/*.rb')
21
+ end
22
+
23
+
24
+
25
+
26
+ Bundler::GemHelper.install_tasks
27
+
@@ -0,0 +1,10 @@
1
+ Description:
2
+ Generates tracked attributes for Model and attributes attr_a attr_b
3
+
4
+ Example:
5
+ rails generate track_it Model attr_a attr_b
6
+
7
+ This will create:
8
+ /db/migrate/add_tracked_attributes_to_models.rb
9
+ And Inject:
10
+ track_attributes :attr_a, :attr_b into /app/models/model.rb
@@ -0,0 +1,10 @@
1
+ class AddTrackedAttributesTo<%= name.camelize.pluralize %> < ActiveRecord::Migration
2
+ def up
3
+ add_column :<%= table_name %>, :tracked_attributes, :integer, :default => 0, :null => false
4
+ end
5
+
6
+ def down
7
+ remove_column :<%= table_name %>, :tracked_attributes
8
+ end
9
+
10
+ end
@@ -0,0 +1,33 @@
1
+ require 'rails/generators/active_record'
2
+ require 'rails/generators/migration'
3
+
4
+ module TrackIt
5
+ module Generators
6
+ class TrackItGenerator < ActiveRecord::Generators::Base
7
+ source_root File.expand_path('../templates', __FILE__)
8
+ argument :attrs, :type => :array, :default => []
9
+
10
+ def generate_track_attributes_call_on_model_file
11
+ inject_into_class model_file_path, model_class, model_content
12
+ end
13
+
14
+ def create_attributes_tracker_migration
15
+ migration_template "migration.rb", "db/migrate/add_tracked_attributes_to_#{table_name}"
16
+ end
17
+
18
+ protected
19
+
20
+ def model_file_path
21
+ File.join("app", "models", "#{name.underscore}.rb")
22
+ end
23
+
24
+ def model_class
25
+ name.camelize.constantize
26
+ end
27
+
28
+ def model_content
29
+ " track_attributes #{attrs.map {|a| ":#{a}"}.join(", ")}\n"
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,36 @@
1
+ module TrackIt
2
+ module TrackAttributes
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ end
7
+
8
+ module ClassMethods
9
+ def track_attributes(*attrs)
10
+ self.class_eval do
11
+ before_save :update_tracked_attributes
12
+ @tracked_attributes = attrs.flatten
13
+ end
14
+ end
15
+
16
+ def tracked_attributes
17
+ @tracked_attributes ||= []
18
+ end
19
+ end
20
+
21
+ def update_tracked_attributes
22
+ changed_attrs = self.changes.keys.map(&:to_sym)
23
+ changed_tracked_attributes = self.class.tracked_attributes.select {|k| changed_attrs.include?(k)}
24
+ changed_tracked_attributes.each do |attr|
25
+ self.tracked.set_changed(attr)
26
+ end
27
+ end
28
+
29
+ def tracked
30
+ @tracked ||= TrackIt::Wrapper.new(self)
31
+ end
32
+
33
+ end
34
+
35
+ end
36
+ ActiveRecord::Base.send :include, TrackIt::TrackAttributes
@@ -0,0 +1,3 @@
1
+ module TrackIt
2
+ VERSION = "0.1"
3
+ end
@@ -0,0 +1,62 @@
1
+ module TrackIt
2
+
3
+ class Wrapper
4
+ include ActiveModel::AttributeMethods
5
+ attribute_method_suffix '_changed?'
6
+ attr_reader :model
7
+
8
+ def initialize(model)
9
+ @model = model
10
+ end
11
+
12
+ def changed?
13
+ model.tracked_attributes != 0
14
+ end
15
+
16
+ def changed
17
+ changed = []
18
+ bits_num = tracked_attributes.size
19
+ (bits_num-1).downto(0) do |i|
20
+ changed << tracked_attributes[i] if model.tracked_attributes[i] == 1
21
+ end
22
+ changed
23
+ end
24
+
25
+ def set_changed(attr)
26
+ @model.tracked_attributes |= 2 ** tracked_attributes.index(attr)
27
+ end
28
+
29
+ def set_unchanged(attr)
30
+ @model.tracked_attributes &= ~(2 ** tracked_attributes.index(attr))
31
+ end
32
+
33
+ def set_all_unchanged
34
+ @model.tracked_attributes = 0
35
+ end
36
+
37
+ def set_all_changed
38
+ @model.tracked_attributes |= (~0)
39
+ end
40
+
41
+
42
+ protected
43
+
44
+ def attributes
45
+ model.attributes.slice(*tracked_attributes.map(&:to_s))
46
+ end
47
+
48
+ def model_class
49
+ model.class
50
+ end
51
+
52
+ def tracked_attributes
53
+ @tracked_attributes ||= model.class.tracked_attributes
54
+ end
55
+
56
+ def attribute_changed?(attr)
57
+ model.tracked_attributes[tracked_attributes.index(attr.to_sym)] == 1
58
+ end
59
+ end
60
+
61
+
62
+ end
data/lib/trackit.rb ADDED
@@ -0,0 +1,5 @@
1
+ require 'trackit/wrapper'
2
+ require 'trackit/track_attributes'
3
+
4
+ module TrackIt
5
+ end
metadata ADDED
@@ -0,0 +1,132 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: trackit
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Erez Rabih
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-07-21 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rails
16
+ requirement: &2169451920 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 3.2.6
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *2169451920
25
+ - !ruby/object:Gem::Dependency
26
+ name: sqlite3
27
+ requirement: &2169451500 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *2169451500
36
+ - !ruby/object:Gem::Dependency
37
+ name: rspec-rails
38
+ requirement: &2169451040 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *2169451040
47
+ - !ruby/object:Gem::Dependency
48
+ name: guard-rspec
49
+ requirement: &2169450620 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *2169450620
58
+ - !ruby/object:Gem::Dependency
59
+ name: guard-spork
60
+ requirement: &2169450200 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *2169450200
69
+ - !ruby/object:Gem::Dependency
70
+ name: growl
71
+ requirement: &2169449780 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *2169449780
80
+ - !ruby/object:Gem::Dependency
81
+ name: debugger
82
+ requirement: &2169449360 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: *2169449360
91
+ description: TrackIt allows you to track attributes changes in your ActiveRecord models
92
+ email:
93
+ - erez.rabih@gmail.com
94
+ executables: []
95
+ extensions: []
96
+ extra_rdoc_files: []
97
+ files:
98
+ - lib/generators/track_it/templates/migration.rb
99
+ - lib/generators/track_it/track_it_generator.rb
100
+ - lib/generators/track_it/USAGE
101
+ - lib/trackit/track_attributes.rb
102
+ - lib/trackit/version.rb
103
+ - lib/trackit/wrapper.rb
104
+ - lib/trackit.rb
105
+ - MIT-LICENSE
106
+ - Rakefile
107
+ - README.md
108
+ homepage: https://github.com/erez-rabih/tracker
109
+ licenses: []
110
+ post_install_message:
111
+ rdoc_options: []
112
+ require_paths:
113
+ - lib
114
+ required_ruby_version: !ruby/object:Gem::Requirement
115
+ none: false
116
+ requirements:
117
+ - - ! '>='
118
+ - !ruby/object:Gem::Version
119
+ version: '0'
120
+ required_rubygems_version: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ requirements: []
127
+ rubyforge_project:
128
+ rubygems_version: 1.7.2
129
+ signing_key:
130
+ specification_version: 3
131
+ summary: TrackIt allows you to track attributes changes in your ActiveRecord models
132
+ test_files: []