mirror of
https://github.com/paper-trail-gem/paper_trail.git
synced 2022-11-09 11:33:19 -05:00
Add info and tests for has_many :through.
This commit is contained in:
parent
2e19ed3e55
commit
f65cd0f722
3 changed files with 110 additions and 0 deletions
40
README.md
40
README.md
|
@ -212,6 +212,46 @@ To find out who made a `version`'s object look that way, use `version.originator
|
|||
>> last_version.terminator # 'Bob'
|
||||
|
||||
|
||||
## Has-Many-Through Associations
|
||||
|
||||
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:
|
||||
|
||||
Given these models:
|
||||
|
||||
class Book < ActiveRecord::Base
|
||||
has_many :authorships, :dependent => :destroy
|
||||
has_many :authors, :through => :authorships, :source => :person
|
||||
has_paper_trail
|
||||
end
|
||||
|
||||
class Authorship < ActiveRecord::Base
|
||||
belongs_to :book
|
||||
belongs_to :person
|
||||
has_paper_trail # NOTE
|
||||
end
|
||||
|
||||
class Person < ActiveRecord::Base
|
||||
has_many :authorships, :dependent => :destroy
|
||||
has_many :books, :through => :authorships
|
||||
has_paper_trail
|
||||
end
|
||||
|
||||
Then each of the following will store authorship versions:
|
||||
|
||||
>> @book.authors << @dostoyevsky
|
||||
>> @book.authors.create :name => 'Tolstoy'
|
||||
>> @book.authorships.last.destroy
|
||||
>> @book.authorships.clear
|
||||
|
||||
But none of these will:
|
||||
|
||||
>> @book.authors.delete @tolstoy
|
||||
>> @book.author_ids = [@solzhenistyn.id, @dostoyevsky.id]
|
||||
>> @book.authors = []
|
||||
|
||||
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.
|
||||
|
||||
|
||||
## Storing metadata
|
||||
|
||||
You can store arbitrary model-level metadata alongside each version like this:
|
||||
|
|
|
@ -24,6 +24,24 @@ class Article < ActiveRecord::Base
|
|||
:article_id => Proc.new { |article| article.id } }
|
||||
end
|
||||
|
||||
class Book < ActiveRecord::Base
|
||||
has_many :authorships, :dependent => :destroy
|
||||
has_many :authors, :through => :authorships, :source => :person
|
||||
has_paper_trail
|
||||
end
|
||||
|
||||
class Authorship < ActiveRecord::Base
|
||||
belongs_to :book
|
||||
belongs_to :person
|
||||
has_paper_trail
|
||||
end
|
||||
|
||||
class Person < ActiveRecord::Base
|
||||
has_many :authorships, :dependent => :destroy
|
||||
has_many :books, :through => :authorships
|
||||
has_paper_trail
|
||||
end
|
||||
|
||||
|
||||
class HasPaperTrailModelTest < Test::Unit::TestCase
|
||||
load_schema
|
||||
|
@ -586,5 +604,44 @@ class HasPaperTrailModelTest < Test::Unit::TestCase
|
|||
end
|
||||
end
|
||||
|
||||
context ":has_many :through" do
|
||||
setup do
|
||||
@book = Book.create :title => 'War and Peace'
|
||||
@dostoyevsky = Person.create :name => 'Dostoyevsky'
|
||||
@solzhenitsyn = Person.create :name => 'Solzhenitsyn'
|
||||
end
|
||||
|
||||
should 'store version on source <<' do
|
||||
count = Version.count
|
||||
@book.authors << @dostoyevsky
|
||||
assert_equal 1, Version.count - count
|
||||
assert_equal Version.last, @book.authorships.first.versions.first
|
||||
end
|
||||
|
||||
should 'store version on source create' do
|
||||
count = Version.count
|
||||
@book.authors.create :name => 'Tolstoy'
|
||||
assert_equal 2, Version.count - count
|
||||
assert_same_elements [Person.last, Authorship.last], [Version.all[-2].item, Version.last.item]
|
||||
end
|
||||
|
||||
should 'store version on join destroy' do
|
||||
@book.authors << @dostoyevsky
|
||||
count = Version.count
|
||||
@book.authorships(true).last.destroy
|
||||
assert_equal 1, Version.count - count
|
||||
assert_equal @book, Version.last.reify.book
|
||||
assert_equal @dostoyevsky, Version.last.reify.person
|
||||
end
|
||||
|
||||
should 'store version on join clear' do
|
||||
@book.authors << @dostoyevsky
|
||||
count = Version.count
|
||||
@book.authorships(true).clear
|
||||
assert_equal 1, Version.count - count
|
||||
assert_equal @book, Version.last.reify.book
|
||||
assert_equal @dostoyevsky, Version.last.reify.person
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -49,4 +49,17 @@ ActiveRecord::Schema.define(:version => 0) do
|
|||
t.string :content
|
||||
end
|
||||
|
||||
create_table :books, :force => true do |t|
|
||||
t.string :title
|
||||
end
|
||||
|
||||
create_table :authorships, :force => true do |t|
|
||||
t.integer :book_id
|
||||
t.integer :person_id
|
||||
end
|
||||
|
||||
create_table :people, :force => true do |t|
|
||||
t.string :name
|
||||
end
|
||||
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue