Skip to content

Commit ce6e160

Browse files
committed
Merge pull request #2865 from lazebny:papertrail-with-inheritance
PaperTrail + Inheritance
2 parents e0b390d + f0de1cf commit ce6e160

File tree

5 files changed

+157
-91
lines changed

5 files changed

+157
-91
lines changed

lib/rails_admin/extensions/paper_trail/auditing_adapter.rb

+15-3
Original file line numberDiff line numberDiff line change
@@ -112,11 +112,9 @@ def listing_for_model_or_object(model, object, query, sort, sort_reverse, all, p
112112
sort_reverse = 'true'
113113
end
114114

115-
ar_model = model.model
116115
current_page = page.presence || '1'
117116

118-
versions = version_class_for(ar_model).where item_type: ar_model.name
119-
versions = versions.where item_id: object.id if object
117+
versions = object.nil? ? versions_for_model(model) : object.versions
120118
versions = versions.where('event LIKE ?', "%#{query}%") if query.present?
121119
versions = versions.order(sort_reverse == 'true' ? "#{sort} DESC" : sort)
122120
versions = all ? versions : versions.send(Kaminari.config.page_method_name, current_page).per(per_page)
@@ -128,6 +126,20 @@ def listing_for_model_or_object(model, object, query, sort, sort_reverse, all, p
128126
paginated_proxies
129127
end
130128

129+
def versions_for_model(model)
130+
model_name = model.model.name
131+
base_class_name = model.model.base_class.name
132+
133+
options =
134+
if base_class_name == model_name
135+
{item_type: model_name}
136+
else
137+
{item_type: base_class_name, item_id: model.model.all}
138+
end
139+
140+
version_class_for(model.model).where(options)
141+
end
142+
131143
# PT can be configured to use [custom version
132144
# classes](https://github.com/paper-trail-gem/paper_trail#6a-custom-version-classes)
133145
#
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
class PaperTrailTest < ActiveRecord::Base
2+
class SubclassInNamespace < self
3+
end
4+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
class PaperTrailTestSubclass < PaperTrailTest
2+
end

spec/factories.rb

+8
Original file line numberDiff line numberDiff line change
@@ -81,5 +81,13 @@
8181

8282
factory :paper_trail_test do
8383
sequence(:name) { |n| "name #{n}" }
84+
85+
factory :paper_trail_test_subclass,
86+
parent: :paper_trail_test,
87+
class: 'PaperTrailTestSubclass'
88+
89+
factory :paper_trail_test_subclass_in_namespace,
90+
parent: :paper_trail_test,
91+
class: 'PaperTrailTest::SubclassInNamespace'
8492
end
8593
end

spec/integration/history/rails_admin_paper_trail_spec.rb

+128-88
Original file line numberDiff line numberDiff line change
@@ -16,124 +16,164 @@
1616
end
1717
end
1818

19-
describe 'on object creation', type: :request do
20-
subject { page }
21-
before do
22-
@user = FactoryBot.create :user
23-
RailsAdmin::Config.authenticate_with { warden.authenticate! scope: :user }
24-
RailsAdmin::Config.current_user_method(&:current_user)
25-
login_as @user
26-
with_versioning do
27-
visit new_path(model_name: 'paper_trail_test')
28-
fill_in 'paper_trail_test[name]', with: 'Jackie Robinson'
29-
click_button 'Save'
30-
@object = RailsAdmin::AbstractModel.new('PaperTrailTest').first
19+
shared_examples :paper_on_object_creation do
20+
describe 'on object creation', type: :request do
21+
subject { page }
22+
before do
23+
@user = FactoryBot.create :user
24+
RailsAdmin::Config.authenticate_with { warden.authenticate! scope: :user }
25+
RailsAdmin::Config.current_user_method(&:current_user)
26+
login_as @user
27+
with_versioning do
28+
visit new_path(model_name: paper_model_name)
29+
fill_in paper_field_name, with: 'Jackie Robinson'
30+
click_button 'Save'
31+
@object = RailsAdmin::AbstractModel.new(paper_class_name).first
32+
end
3133
end
32-
end
3334

34-
it 'records a version' do
35-
expect(@object.versions.size).to eq 1
36-
expect(@object.versions.first.whodunnit).to eq @user.id.to_s
35+
it 'records a version' do
36+
expect(@object.versions.size).to eq 1
37+
expect(@object.versions.first.whodunnit).to eq @user.id.to_s
38+
end
3739
end
3840
end
3941

40-
describe 'model history fetch' do
41-
before(:each) do
42-
PaperTrail::Version.delete_all
43-
@model = RailsAdmin::AbstractModel.new('PaperTrailTest')
44-
@user = FactoryBot.create :user
45-
@paper_trail_test = FactoryBot.create :paper_trail_test
46-
with_versioning do
47-
# `PaperTrail.whodunnit` deprecated in PT 9, will be removed in 10.
48-
# Use `PaperTrail.request.whodunnit` instead.
49-
if PaperTrail.respond_to?(:request)
50-
PaperTrail.request.whodunnit = @user.id
51-
else
52-
PaperTrail.whodunnit = @user.id
53-
end
54-
30.times do |i|
55-
@paper_trail_test.update!(name: "updated name #{i}")
42+
shared_examples :paper_history do
43+
describe 'model history fetch' do
44+
before(:each) do
45+
PaperTrail::Version.delete_all
46+
@model = RailsAdmin::AbstractModel.new(paper_class_name)
47+
@user = FactoryBot.create :user
48+
@paper_trail_test = FactoryBot.create(paper_factory)
49+
with_versioning do
50+
# `PaperTrail.whodunnit` deprecated in PT 9, will be removed in 10.
51+
# Use `PaperTrail.request.whodunnit` instead.
52+
if PaperTrail.respond_to?(:request)
53+
PaperTrail.request.whodunnit = @user.id
54+
else
55+
PaperTrail.whodunnit = @user.id
56+
end
57+
30.times do |i|
58+
@paper_trail_test.update!(name: "updated name #{i}")
59+
end
5660
end
5761
end
58-
end
59-
60-
it 'creates versions' do
61-
expect(PaperTrail::Version.count).to eq(30)
62-
end
63-
64-
describe 'model history fetch with auditing adapter' do
65-
before(:all) do
66-
@adapter = RailsAdmin::Extensions::PaperTrail::AuditingAdapter.new(nil, 'User', 'PaperTrail::Version')
67-
end
6862

69-
it 'fetches on page of history' do
70-
versions = @adapter.listing_for_model @model, nil, false, false, false, nil, 20
71-
expect(versions.total_count).to eq(30)
72-
expect(versions.count).to eq(20)
63+
it 'creates versions' do
64+
expect(PaperTrail::Version.count).to eq(30)
7365
end
7466

75-
it 'respects RailsAdmin::Config.default_items_per_page' do
76-
RailsAdmin.config.default_items_per_page = 15
77-
versions = @adapter.listing_for_model @model, nil, false, false, false, nil
78-
expect(versions.total_count).to eq(30)
79-
expect(versions.count).to eq(15)
80-
end
81-
82-
it 'sets correct next page' do
83-
versions = @adapter.listing_for_model @model, nil, false, false, false, 2, 10
84-
expect(versions.next_page).to eq(3)
85-
end
67+
describe 'model history fetch with auditing adapter' do
68+
before(:all) do
69+
@adapter = RailsAdmin::Extensions::PaperTrail::AuditingAdapter.new(nil, 'User', 'PaperTrail::Version')
70+
end
8671

87-
it 'can fetch all history' do
88-
versions = @adapter.listing_for_model @model, nil, false, false, true, nil, 20
89-
expect(versions.total_count).to eq(30)
90-
expect(versions.count).to eq(30)
91-
end
72+
it 'fetches on page of history' do
73+
versions = @adapter.listing_for_model @model, nil, false, false, false, nil, 20
74+
expect(versions.total_count).to eq(30)
75+
expect(versions.count).to eq(20)
76+
end
9277

93-
describe 'returned version objects' do
94-
before(:each) do
95-
@padinated_listing = @adapter.listing_for_model @model, nil, false, false, false, nil
96-
@version = @padinated_listing.first
78+
it 'respects RailsAdmin::Config.default_items_per_page' do
79+
RailsAdmin.config.default_items_per_page = 15
80+
versions = @adapter.listing_for_model @model, nil, false, false, false, nil
81+
expect(versions.total_count).to eq(30)
82+
expect(versions.count).to eq(15)
9783
end
9884

99-
it '#username returns user email' do
100-
expect(@version.username).to eq(@user.email)
85+
it 'sets correct next page' do
86+
versions = @adapter.listing_for_model @model, nil, false, false, false, 2, 10
87+
expect(versions.next_page).to eq(3)
10188
end
10289

103-
it '#message returns event' do
104-
expect(@version.message).to eq('update')
90+
it 'can fetch all history' do
91+
versions = @adapter.listing_for_model @model, nil, false, false, true, nil, 20
92+
expect(versions.total_count).to eq(30)
93+
expect(versions.count).to eq(30)
10594
end
10695

107-
describe 'changed item attributes' do
108-
it '#item returns item.id' do
109-
expect(@version.item).to eq(@paper_trail_test.id)
96+
describe 'returned version objects' do
97+
before(:each) do
98+
@padinated_listing = @adapter.listing_for_model @model, nil, false, false, false, nil
99+
@version = @padinated_listing.first
110100
end
111101

112-
it '#table returns item class name' do
113-
expect(@version.table.to_s).to eq('PaperTrailTest')
102+
it '#username returns user email' do
103+
expect(@version.username).to eq(@user.email)
114104
end
115-
end
116105

117-
context 'with Kaminari' do
118-
before do
119-
Kaminari.config.page_method_name = :per_page_kaminari
106+
it '#message returns event' do
107+
expect(@version.message).to eq('update')
120108
end
121109

122-
after do
123-
Kaminari.config.page_method_name = :page
110+
describe 'changed item attributes' do
111+
it '#item returns item.id' do
112+
expect(@version.item).to eq(@paper_trail_test.id)
113+
end
114+
115+
it '#table returns item class name' do
116+
expect(@version.table.to_s).to eq('PaperTrailTest')
117+
end
124118
end
125119

126-
let(:paginated_array) { Kaminari::PaginatableArray.new.page('1') }
120+
context 'with Kaminari' do
121+
before do
122+
Kaminari.config.page_method_name = :per_page_kaminari
123+
end
124+
125+
after do
126+
Kaminari.config.page_method_name = :page
127+
end
128+
129+
let(:paginated_array) { Kaminari::PaginatableArray.new.page('1') }
127130

128-
it "supports pagination when Kaminari's page_method_name is customized" do
129-
expect(PaperTrail::Version).to receive(:per_page_kaminari).twice.and_return(@padinated_listing)
130-
allow(Kaminari).to receive(:paginate_array).and_return(paginated_array)
131-
expect(paginated_array).to receive(:per_page_kaminari).twice.and_return(paginated_array)
132-
@adapter.listing_for_model @model, nil, false, false, false, nil
133-
@adapter.listing_for_object @model, @paper_trail_test, nil, false, false, false, nil
131+
it "supports pagination when Kaminari's page_method_name is customized" do
132+
expect(PaperTrail::Version).to receive(:per_page_kaminari).twice.and_return(@padinated_listing)
133+
allow(Kaminari).to receive(:paginate_array).and_return(paginated_array)
134+
expect(paginated_array).to receive(:per_page_kaminari).twice.and_return(paginated_array)
135+
@adapter.listing_for_model @model, nil, false, false, false, nil
136+
@adapter.listing_for_object @model, @paper_trail_test, nil, false, false, false, nil
137+
end
134138
end
135139
end
136140
end
137141
end
138142
end
143+
144+
context 'PaperTrailTest' do
145+
let(:paper_class_name) { 'PaperTrailTest' }
146+
let(:paper_factory) { :paper_trail_test }
147+
148+
it_behaves_like :paper_on_object_creation do
149+
let(:paper_model_name) { 'paper_trail_test' }
150+
let(:paper_field_name) { 'paper_trail_test[name]' }
151+
end
152+
153+
it_behaves_like :paper_history
154+
end
155+
156+
context 'PaperTrailTestSubclass' do
157+
let(:paper_class_name) { 'PaperTrailTestSubclass' }
158+
let(:paper_factory) { :paper_trail_test_subclass }
159+
160+
it_behaves_like :paper_on_object_creation do
161+
let(:paper_model_name) { 'paper_trail_test_subclass' }
162+
let(:paper_field_name) { 'paper_trail_test_subclass[name]' }
163+
end
164+
165+
it_behaves_like :paper_history
166+
end
167+
168+
context 'PaperTrailTest::SubclassInNamespace' do
169+
let(:paper_class_name) { 'PaperTrailTest::SubclassInNamespace' }
170+
let(:paper_factory) { :paper_trail_test_subclass_in_namespace }
171+
172+
it_behaves_like :paper_on_object_creation do
173+
let(:paper_model_name) { 'paper_trail_test~subclass_in_namespace' }
174+
let(:paper_field_name) { 'paper_trail_test_subclass_in_namespace[name]' }
175+
end
176+
177+
it_behaves_like :paper_history
178+
end
139179
end

0 commit comments

Comments
 (0)