Skip to content

Commit 951b708

Browse files
committed
Add block-style DSL support for extension adapters
1 parent 4cc3f30 commit 951b708

10 files changed

Lines changed: 133 additions & 44 deletions

File tree

lib/rails_admin/config.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ def audit_with(*args, &block)
119119
klass = RailsAdmin::AUDITING_ADAPTERS[extension]
120120
klass.setup if klass.respond_to? :setup
121121
@audit = proc do
122-
@auditing_adapter = klass.new(*([self] + args).compact)
122+
@auditing_adapter = klass.new(*([self] + args).compact, &block)
123123
end
124124
elsif block
125125
@audit = block
@@ -156,7 +156,7 @@ def authorize_with(*args, &block)
156156
klass = RailsAdmin::AUTHORIZATION_ADAPTERS[extension]
157157
klass.setup if klass.respond_to? :setup
158158
@authorize = proc do
159-
@authorization_adapter = klass.new(*([self] + args).compact)
159+
@authorization_adapter = klass.new(*([self] + args).compact, &block)
160160
end
161161
elsif block
162162
@authorize = block

lib/rails_admin/extensions/cancancan/authorization_adapter.rb

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,33 @@ module ControllerExtension
99
def current_ability
1010
# use _current_user instead of default current_user so it works with
1111
# whatever current user method is defined with RailsAdmin
12-
@current_ability ||= @ability.new(_current_user)
12+
@current_ability ||= ability_class.new(_current_user)
1313
end
1414
end
1515

16+
include RailsAdmin::Config::Configurable
17+
18+
def self.setup
19+
RailsAdmin::Extensions::ControllerExtension.include ControllerExtension
20+
end
21+
1622
# See the +authorize_with+ config method for where the initialization happens.
17-
def initialize(controller, ability = ::Ability)
23+
def initialize(controller, ability = nil, &block)
1824
@controller = controller
19-
@controller.instance_variable_set '@ability', ability
20-
@controller.extend ControllerExtension
25+
ability_class { ability } if ability
26+
instance_eval(&block) if block
27+
28+
adapter = self
29+
ControllerExtension.define_method(:ability_class) do
30+
adapter.ability_class
31+
end
2132
@controller.current_ability.authorize! :access, :rails_admin
2233
end
2334

35+
register_instance_option :ability_class do
36+
Ability
37+
end
38+
2439
# This method is called in every controller action and should raise an exception
2540
# when the authorization fails. The first argument is the name of the controller
2641
# action as a symbol (:create, :bulk_delete, etc.). The second argument is the

lib/rails_admin/extensions/paper_trail/auditing_adapter.rb

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -51,43 +51,59 @@ class AuditingAdapter
5151
created_at: :created_at,
5252
message: :event,
5353
}.freeze
54+
E_USER_CLASS_NOT_SET = <<~ERROR
55+
Please set up PaperTrail's user class explicitly.
56+
57+
config.audit_with :paper_trail do
58+
user_class { User }
59+
end
60+
ERROR
5461
E_VERSION_MODEL_NOT_SET = <<~ERROR
5562
Please set up PaperTrail's version model explicitly.
5663
57-
config.audit_with :paper_trail, 'User', 'PaperTrail::Version'
64+
config.audit_with :paper_trail do
65+
version_class { PaperTrail::Version }
66+
end
5867
5968
If you have configured a model to use a custom version class
6069
(https://github.com/paper-trail-gem/paper_trail#6a-custom-version-classes)
61-
that configuration will take precedence over what you specify in
62-
`audit_with`.
70+
that configuration will take precedence over what you specify in `audit_with`.
6371
ERROR
6472

73+
include RailsAdmin::Config::Configurable
74+
6575
def self.setup
6676
raise 'PaperTrail not found' unless defined?(::PaperTrail)
6777

6878
RailsAdmin::Extensions::ControllerExtension.include ControllerExtension
6979
end
7080

71-
def initialize(controller, user_class = 'User', version_class = '::Version')
81+
def initialize(controller, user_class_name = nil, version_class_name = nil, &block)
7282
@controller = controller
7383
@controller&.send(:set_paper_trail_whodunnit)
74-
begin
75-
@user_class = user_class.to_s.constantize
76-
rescue NameError
77-
raise "Please set up Papertrail's user model explicitly. Ex: config.audit_with :paper_trail, 'User'"
78-
end
7984

80-
begin
81-
@version_class = version_class.to_s.constantize
82-
rescue NameError
83-
raise E_VERSION_MODEL_NOT_SET
84-
end
85+
user_class { user_class_name.to_s.constantize } if user_class_name
86+
version_class { version_class_name.to_s.constantize } if version_class_name
87+
88+
instance_eval(&block) if block
89+
end
90+
91+
register_instance_option :user_class do
92+
User
93+
rescue NameError
94+
raise E_USER_CLASS_NOT_SET
95+
end
96+
97+
register_instance_option :version_class do
98+
PaperTrail::Version
99+
rescue NameError
100+
raise E_VERSION_MODEL_NOT_SET
85101
end
86102

87103
def latest(count = 100)
88-
@version_class.
104+
version_class.
89105
order(id: :desc).includes(:item).limit(count).
90-
collect { |version| VersionProxy.new(version, @user_class) }
106+
collect { |version| VersionProxy.new(version, user_class) }
91107
end
92108

93109
def delete_object(_object, _model, _user)
@@ -133,7 +149,7 @@ def listing_for_model_or_object(model, object, query, sort, sort_reverse, all, p
133149
current_page,
134150
).per(per_page)
135151
versions.each do |version|
136-
paginated_proxies << VersionProxy.new(version, @user_class)
152+
paginated_proxies << VersionProxy.new(version, user_class)
137153
end
138154
paginated_proxies
139155
end
@@ -159,7 +175,7 @@ def versions_for_model(model)
159175
# has_paper_trail versions: { class_name: 'MyVersion' }
160176
# ```
161177
def version_class_for(model)
162-
model.paper_trail_options.dig(:versions, :class_name).try(:constantize) || @version_class
178+
model.paper_trail.version_class
163179
end
164180
end
165181
end

spec/dummy_app/app/active_record/paper_trail_test_with_custom_association.rb

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
# frozen_string_literal: true
22

3-
class Trail < PaperTrail::Version
4-
self.table_name = :custom_versions
5-
end
6-
73
class PaperTrailTestWithCustomAssociation < ActiveRecord::Base
84
self.table_name = :paper_trail_tests
95
has_paper_trail versions: {class_name: 'Trail'}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# frozen_string_literal: true
2+
3+
class Trail < PaperTrail::Version
4+
self.table_name = :custom_versions
5+
end

spec/integration/auditing/rails_admin_paper_trail_spec.rb renamed to spec/integration/auditing/paper_trail_spec.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
RSpec.describe 'RailsAdmin PaperTrail auditing', active_record: true do
66
before(:each) do
77
RailsAdmin.config do |config|
8-
config.audit_with :paper_trail, 'User', 'PaperTrail::Version'
8+
config.audit_with :paper_trail
99
end
1010
end
1111

@@ -59,7 +59,7 @@
5959

6060
describe 'model history fetch with auditing adapter' do
6161
before(:all) do
62-
@adapter = RailsAdmin::Extensions::PaperTrail::AuditingAdapter.new(nil, 'User', 'PaperTrail::Version')
62+
@adapter = RailsAdmin::Extensions::PaperTrail::AuditingAdapter.new(nil)
6363
end
6464

6565
it 'fetches on page of history' do

spec/integration/authorization/cancancan_spec.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,11 @@ def initialize(user)
310310

311311
describe 'with a custom admin ability' do
312312
before do
313-
RailsAdmin.config { |c| c.authorize_with :cancancan, AdminAbility }
313+
RailsAdmin.config do |c|
314+
c.authorize_with :cancancan do
315+
ability_class { AdminAbility }
316+
end
317+
end
314318
@user = FactoryBot.create :user
315319
login_as @user
316320
end
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# frozen_string_literal: true
2+
3+
require 'spec_helper'
4+
5+
RSpec.describe RailsAdmin::Extensions::CanCanCan::AuthorizationAdapter do
6+
let(:user) { double }
7+
let(:controller) { double(_current_user: user, current_ability: MyAbility.new(user)) }
8+
9+
class MyAbility
10+
include CanCan::Ability
11+
def initialize(_user)
12+
can :access, :rails_admin
13+
can :manage, :all
14+
end
15+
end
16+
17+
describe '#initialize' do
18+
it 'accepts the ability class as an argument' do
19+
expect(described_class.new(controller, MyAbility).ability_class).to eq MyAbility
20+
end
21+
22+
it 'supports block DSL' do
23+
adapter = described_class.new(controller) do
24+
ability_class MyAbility
25+
end
26+
expect(adapter.ability_class).to eq MyAbility
27+
end
28+
end
29+
end

spec/rails_admin/extentions/paper_trail/auditing_adapter_spec.rb

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,23 @@
22

33
require 'spec_helper'
44

5-
RSpec.describe RailsAdmin::Extensions::PaperTrail::VersionProxy do
6-
describe '#username' do
7-
subject { described_class.new(version, user_class).username }
5+
RSpec.describe RailsAdmin::Extensions::PaperTrail::AuditingAdapter, active_record: true do
6+
let(:controller) { double(set_paper_trail_whodunnit: nil) }
87

9-
let(:version) { double(whodunnit: :the_user) }
10-
let(:user_class) { double(find: user) }
11-
12-
context 'when found user has email' do
13-
let(:user) { double(email: :mail) }
14-
it { is_expected.to eq(:mail) }
8+
describe '#initialize' do
9+
it 'accepts the user and version classes as arguments' do
10+
adapter = described_class.new(controller, User::Confirmed, Trail)
11+
expect(adapter.user_class).to eq User::Confirmed
12+
expect(adapter.version_class).to eq Trail
1513
end
1614

17-
context 'when found user does not have email' do
18-
let(:user) { double } # no email method
19-
20-
it { is_expected.to eq(:the_user) }
15+
it 'supports block DSL' do
16+
adapter = described_class.new(controller) do
17+
user_class User::Confirmed
18+
version_class Trail
19+
end
20+
expect(adapter.user_class).to eq User::Confirmed
21+
expect(adapter.version_class).to eq Trail
2122
end
2223
end
2324
end
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# frozen_string_literal: true
2+
3+
require 'spec_helper'
4+
5+
RSpec.describe RailsAdmin::Extensions::PaperTrail::VersionProxy, active_record: true do
6+
describe '#username' do
7+
subject { described_class.new(version, user_class).username }
8+
9+
let(:version) { double(whodunnit: :the_user) }
10+
let(:user_class) { double(find: user) }
11+
12+
context 'when found user has email' do
13+
let(:user) { double(email: :mail) }
14+
it { is_expected.to eq(:mail) }
15+
end
16+
17+
context 'when found user does not have email' do
18+
let(:user) { double } # no email method
19+
20+
it { is_expected.to eq(:the_user) }
21+
end
22+
end
23+
end

0 commit comments

Comments
 (0)