Skip to content

Commit 9ef5b29

Browse files
committed
Fix #3541 breaking on reload with parent_controller set
1 parent 94f16fb commit 9ef5b29

File tree

4 files changed

+77
-12
lines changed

4 files changed

+77
-12
lines changed

lib/rails_admin.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def self.config(entity = nil, &block)
3232
if entity
3333
RailsAdmin::Config.model(entity, &block)
3434
elsif block_given?
35-
suppress_const_load { yield(RailsAdmin::Config) }
35+
RailsAdmin::Config::ConstLoadSuppressor.suppressing { yield(RailsAdmin::Config) }
3636
else
3737
RailsAdmin::Config
3838
end

lib/rails_admin/config.rb

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -270,10 +270,12 @@ def parent_controller=(name)
270270
@parent_controller = name
271271

272272
if defined?(RailsAdmin::ApplicationController) || defined?(RailsAdmin::MainController)
273-
RailsAdmin.send(:remove_const, :ApplicationController)
274-
RailsAdmin.send(:remove_const, :MainController)
275-
load RailsAdmin::Engine.root.join('app/controllers/rails_admin/application_controller.rb')
276-
load RailsAdmin::Engine.root.join('app/controllers/rails_admin/main_controller.rb')
273+
RailsAdmin::Config::ConstLoadSuppressor.allowing do
274+
RailsAdmin.send(:remove_const, :ApplicationController)
275+
RailsAdmin.send(:remove_const, :MainController)
276+
load RailsAdmin::Engine.root.join('app/controllers/rails_admin/application_controller.rb')
277+
load RailsAdmin::Engine.root.join('app/controllers/rails_admin/main_controller.rb')
278+
end
277279
end
278280
end
279281

lib/rails_admin/config/const_load_suppressor.rb

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,40 @@
33
module RailsAdmin
44
module Config
55
module ConstLoadSuppressor
6-
def suppress_const_load
7-
original = Object.method(:const_missing)
8-
Object.define_singleton_method(:const_missing) do |name|
9-
ConstProxy.new(name.to_s)
6+
class << self
7+
@original_const_missing = nil
8+
9+
def suppressing
10+
raise 'Constant Loading is already suppressed' if @original_const_missing
11+
12+
begin
13+
@original_const_missing = Object.method(:const_missing)
14+
intercept_const_missing
15+
yield
16+
ensure
17+
Object.define_singleton_method(:const_missing, @original_const_missing)
18+
@original_const_missing = nil
19+
end
20+
end
21+
22+
def allowing
23+
raise 'Constant Loading is not suppressed' unless @original_const_missing
24+
25+
begin
26+
Object.define_singleton_method(:const_missing, @original_const_missing)
27+
yield
28+
ensure
29+
intercept_const_missing
30+
end
31+
end
32+
33+
private
34+
35+
def intercept_const_missing
36+
Object.define_singleton_method(:const_missing) do |name|
37+
ConstProxy.new(name.to_s)
38+
end
1039
end
11-
yield
12-
ensure
13-
Object.define_singleton_method(:const_missing, original)
1440
end
1541

1642
class ConstProxy < BasicObject
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# frozen_string_literal: true
2+
3+
require 'spec_helper'
4+
5+
RSpec.describe RailsAdmin::Config::ConstLoadSuppressor do
6+
describe '.suppressing' do
7+
it 'suppresses constant loading' do
8+
expect do
9+
subject.suppressing { UnknownConstant }
10+
end.not_to raise_error
11+
end
12+
13+
it 'raises the error on recursion' do
14+
expect do
15+
subject.suppressing do
16+
subject.suppressing {}
17+
end
18+
end.to raise_error(/already suppressed/)
19+
end
20+
end
21+
22+
describe '.allowing' do
23+
it 'suspends constant loading suppression' do
24+
expect do
25+
subject.suppressing do
26+
subject.allowing { UnknownConstant }
27+
end
28+
end.to raise_error NameError
29+
end
30+
31+
it 'raises the error when no suppression is enforced' do
32+
expect do
33+
subject.allowing {}
34+
end.to raise_error(/not suppressed/)
35+
end
36+
end
37+
end

0 commit comments

Comments
 (0)