paper_trail 1.5.2 → 1.5.3

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
@@ -25,7 +25,7 @@ PaperTrail lets you track changes to your models' data. It's good for auditing
25
25
 
26
26
  ## Rails Version
27
27
 
28
- Reported to work on Rails 3 (though I haven't yet tried myself). Known to work on Rails 2.3. Probably works on Rails 2.2 and 2.1.
28
+ Works on Rails 3 and Rails 2.3. Probably works on Rails 2.2 and 2.1.
29
29
 
30
30
 
31
31
  ## Basic Usage
@@ -212,6 +212,48 @@ To find out who made a `version`'s object look that way, use `version.originator
212
212
  >> last_version.terminator # 'Bob'
213
213
 
214
214
 
215
+ ## Has-Many-Through Associations
216
+
217
+ PaperTrail can track most changes to the join table. Specifically it can track all additions but it can only track removals which fire the `after_destroy` callback on the join table. Here are some examples:
218
+
219
+ Given these models:
220
+
221
+ class Book < ActiveRecord::Base
222
+ has_many :authorships, :dependent => :destroy
223
+ has_many :authors, :through => :authorships, :source => :person
224
+ has_paper_trail
225
+ end
226
+
227
+ class Authorship < ActiveRecord::Base
228
+ belongs_to :book
229
+ belongs_to :person
230
+ has_paper_trail # NOTE
231
+ end
232
+
233
+ class Person < ActiveRecord::Base
234
+ has_many :authorships, :dependent => :destroy
235
+ has_many :books, :through => :authorships
236
+ has_paper_trail
237
+ end
238
+
239
+ Then each of the following will store authorship versions:
240
+
241
+ >> @book.authors << @dostoyevsky
242
+ >> @book.authors.create :name => 'Tolstoy'
243
+ >> @book.authorships.last.destroy
244
+ >> @book.authorships.clear
245
+
246
+ But none of these will:
247
+
248
+ >> @book.authors.delete @tolstoy
249
+ >> @book.author_ids = [@solzhenistyn.id, @dostoyevsky.id]
250
+ >> @book.authors = []
251
+
252
+ Having said that, you can probably (I haven't tested it myself) get the first one (`@book.authors.delete @tolstoy`) working with this [monkey patch](http://stackoverflow.com/questions/2381033/how-to-create-a-full-audit-log-in-rails-for-every-table/2381411#2381411). Many thanks to Danny Trelogan for pointing it out.
253
+
254
+ There may be a way to store authorship versions, probably using association callbacks, no matter how the collection is manipulated but I haven't found it yet. Let me know if you do.
255
+
256
+
215
257
  ## Storing metadata
216
258
 
217
259
  You can store arbitrary model-level metadata alongside each version like this:
@@ -315,9 +357,27 @@ Over time your `versions` table will grow to an unwieldy size. Because each ver
315
357
 
316
358
  ## Installation
317
359
 
360
+ ### Rails 3
361
+
362
+ 1. Install PaperTrail as a gem via your `Gemfile`:
363
+
364
+ `gem 'paper_trail'`
365
+
366
+ 2. Generate a migration which will add a `versions` table to your database.
367
+
368
+ `rails generate paper_trail`
369
+
370
+ 3. Run the migration.
371
+
372
+ `rake db:migrate`
373
+
374
+ 4. Add `has_paper_trail` to the models you want to track.
375
+
376
+ ### Rails 2
377
+
318
378
  1. Install PaperTrail as a gem via your `config/environment.rb`:
319
379
 
320
- `config.gem 'paper_trail'
380
+ `config.gem 'paper_trail'`
321
381
 
322
382
  2. Generate a migration which will add a `versions` table to your database.
323
383
 
@@ -353,6 +413,7 @@ Many thanks to:
353
413
  * [Jeremy Weiskotten](http://github.com/jeremyw)
354
414
  * [Phan Le](http://github.com/revo)
355
415
  * [jdrucza](http://github.com/jdrucza)
416
+ * [conickal](http://github.com/conickal)
356
417
 
357
418
 
358
419
  ## Inspirations
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.5.2
1
+ 1.5.3
@@ -0,0 +1,2 @@
1
+ Description:
2
+ Generates (but does not run) a migration to add a versions table.
@@ -0,0 +1,24 @@
1
+ require 'rails/generators/named_base'
2
+ require 'rails/generators/migration'
3
+
4
+ class PaperTrailGenerator < Rails::Generators::NamedBase
5
+ include Rails::Generators::Migration
6
+
7
+ desc "Generates (but does not run) a migration to add a versions table."
8
+ source_root File.expand_path('../templates', __FILE__)
9
+ argument :name, :type => :string, :default => "create_versions"
10
+
11
+ # Implement the required interface for Rails::Generators::Migration.
12
+ # taken from http://github.com/rails/rails/blob/master/activerecord/lib/generators/active_record.rb
13
+ def self.next_migration_number(dirname)
14
+ if ActiveRecord::Base.timestamped_migrations
15
+ Time.now.utc.strftime("%Y%m%d%H%M%S")
16
+ else
17
+ "%.3d" % (current_migration_number(dirname) + 1)
18
+ end
19
+ end
20
+
21
+ def create_migration_file
22
+ migration_template 'create_versions.rb', 'db/migrate/create_versions.rb'
23
+ end
24
+ end
@@ -0,0 +1,18 @@
1
+ class CreateVersions < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :versions do |t|
4
+ t.string :item_type, :null => false
5
+ t.integer :item_id, :null => false
6
+ t.string :event, :null => false
7
+ t.string :whodunnit
8
+ t.text :object
9
+ t.datetime :created_at
10
+ end
11
+ add_index :versions, [:item_type, :item_id]
12
+ end
13
+
14
+ def self.down
15
+ remove_index :versions, [:item_type, :item_id]
16
+ drop_table :versions
17
+ end
18
+ end
data/lib/paper_trail.rb CHANGED
@@ -51,8 +51,6 @@ module PaperTrail
51
51
  private
52
52
 
53
53
  # Thread-safe hash to hold PaperTrail's data.
54
- #
55
- # TODO: is this a memory leak?
56
54
  def self.paper_trail_store
57
55
  Thread.current[:paper_trail] ||= {}
58
56
  end
data/paper_trail.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{paper_trail}
8
- s.version = "1.5.2"
8
+ s.version = "1.5.3"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Andy Stewart"]
12
- s.date = %q{2010-06-28}
12
+ s.date = %q{2010-10-11}
13
13
  s.email = %q{boss@airbladesoftware.com}
14
14
  s.extra_rdoc_files = [
15
15
  "README.md"
@@ -25,6 +25,9 @@ Gem::Specification.new do |s|
25
25
  "generators/paper_trail/templates/create_versions.rb",
26
26
  "init.rb",
27
27
  "install.rb",
28
+ "lib/generators/paper_trail/USAGE",
29
+ "lib/generators/paper_trail/paper_trail_generator.rb",
30
+ "lib/generators/paper_trail/templates/create_versions.rb",
28
31
  "lib/paper_trail.rb",
29
32
  "lib/paper_trail/config.rb",
30
33
  "lib/paper_trail/controller.rb",
@@ -24,6 +24,24 @@ class Article < ActiveRecord::Base
24
24
  :article_id => Proc.new { |article| article.id } }
25
25
  end
26
26
 
27
+ class Book < ActiveRecord::Base
28
+ has_many :authorships, :dependent => :destroy
29
+ has_many :authors, :through => :authorships, :source => :person
30
+ has_paper_trail
31
+ end
32
+
33
+ class Authorship < ActiveRecord::Base
34
+ belongs_to :book
35
+ belongs_to :person
36
+ has_paper_trail
37
+ end
38
+
39
+ class Person < ActiveRecord::Base
40
+ has_many :authorships, :dependent => :destroy
41
+ has_many :books, :through => :authorships
42
+ has_paper_trail
43
+ end
44
+
27
45
 
28
46
  class HasPaperTrailModelTest < Test::Unit::TestCase
29
47
  load_schema
@@ -586,5 +604,44 @@ class HasPaperTrailModelTest < Test::Unit::TestCase
586
604
  end
587
605
  end
588
606
 
607
+ context ":has_many :through" do
608
+ setup do
609
+ @book = Book.create :title => 'War and Peace'
610
+ @dostoyevsky = Person.create :name => 'Dostoyevsky'
611
+ @solzhenitsyn = Person.create :name => 'Solzhenitsyn'
612
+ end
613
+
614
+ should 'store version on source <<' do
615
+ count = Version.count
616
+ @book.authors << @dostoyevsky
617
+ assert_equal 1, Version.count - count
618
+ assert_equal Version.last, @book.authorships.first.versions.first
619
+ end
620
+
621
+ should 'store version on source create' do
622
+ count = Version.count
623
+ @book.authors.create :name => 'Tolstoy'
624
+ assert_equal 2, Version.count - count
625
+ assert_same_elements [Person.last, Authorship.last], [Version.all[-2].item, Version.last.item]
626
+ end
627
+
628
+ should 'store version on join destroy' do
629
+ @book.authors << @dostoyevsky
630
+ count = Version.count
631
+ @book.authorships(true).last.destroy
632
+ assert_equal 1, Version.count - count
633
+ assert_equal @book, Version.last.reify.book
634
+ assert_equal @dostoyevsky, Version.last.reify.person
635
+ end
636
+
637
+ should 'store version on join clear' do
638
+ @book.authors << @dostoyevsky
639
+ count = Version.count
640
+ @book.authorships(true).clear
641
+ assert_equal 1, Version.count - count
642
+ assert_equal @book, Version.last.reify.book
643
+ assert_equal @dostoyevsky, Version.last.reify.person
644
+ end
645
+ end
589
646
 
590
647
  end
data/test/schema.rb CHANGED
@@ -49,4 +49,17 @@ ActiveRecord::Schema.define(:version => 0) do
49
49
  t.string :content
50
50
  end
51
51
 
52
+ create_table :books, :force => true do |t|
53
+ t.string :title
54
+ end
55
+
56
+ create_table :authorships, :force => true do |t|
57
+ t.integer :book_id
58
+ t.integer :person_id
59
+ end
60
+
61
+ create_table :people, :force => true do |t|
62
+ t.string :name
63
+ end
64
+
52
65
  end
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
  - 5
9
- - 2
10
- version: 1.5.2
9
+ - 3
10
+ version: 1.5.3
11
11
  platform: ruby
12
12
  authors:
13
13
  - Andy Stewart
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-06-28 00:00:00 +01:00
18
+ date: 2010-10-11 00:00:00 +01:00
19
19
  default_executable:
20
20
  dependencies: []
21
21
 
@@ -38,6 +38,9 @@ files:
38
38
  - generators/paper_trail/templates/create_versions.rb
39
39
  - init.rb
40
40
  - install.rb
41
+ - lib/generators/paper_trail/USAGE
42
+ - lib/generators/paper_trail/paper_trail_generator.rb
43
+ - lib/generators/paper_trail/templates/create_versions.rb
41
44
  - lib/paper_trail.rb
42
45
  - lib/paper_trail/config.rb
43
46
  - lib/paper_trail/controller.rb