trackit 0.1

Sign up to get free protection for your applications and to get access to all the features.
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: []