Skip to content

Commit 077aced

Browse files
committed
maintain 3.x deferred initializer block config
In 3.x the initializer config blocks are intentionally deferred to allow referencing model classes without quoting. Here is a first pass at keeping that behavior on top of ec03eb6. It could probably use a little cleanup but here's an idea of an approach for feedback. See railsadminteam#3492 (comment) for details.
1 parent ec03eb6 commit 077aced

File tree

6 files changed

+84
-38
lines changed

6 files changed

+84
-38
lines changed

.rubocop.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,10 +115,10 @@ Metrics/CyclomaticComplexity:
115115

116116
Metrics/MethodLength:
117117
CountComments: false
118-
Max: 29 # TODO: Lower to 15
118+
Max: 30 # TODO: Lower to 15
119119

120120
Metrics/ModuleLength:
121-
Max: 228 # TODO: Lower to 100
121+
Max: 248 # TODO: Lower to 100
122122

123123
Metrics/ParameterLists:
124124
Max: 8 # TODO: Lower to 4

lib/rails_admin.rb

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,7 @@ def self.config(entity = nil, &block)
2929
if entity
3030
RailsAdmin::Config.model(entity, &block)
3131
elsif block_given?
32-
# Immediately evaluate non-model (initializer) config. It's needed to
33-
# properly configure routes when there are custom actions.
34-
yield RailsAdmin::Config
32+
RailsAdmin::Config.apply_core(&block)
3533
else
3634
RailsAdmin::Config
3735
end

lib/rails_admin/config.rb

Lines changed: 45 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,12 @@ module Config
2323
DEFAULT_CURRENT_USER = proc {}
2424

2525
# Variables to track initialization process
26-
@initialized = false
27-
@initializing = false
28-
@deferred_blocks = []
26+
@initialized_core = false
27+
@initializing_core = false
28+
@deferred_core_blocks = []
29+
@initialized_models = false
30+
@initializing_models = false
31+
@deferred_model_blocks = []
2932

3033
class << self
3134
# Application title, can be an array of two elements
@@ -86,22 +89,42 @@ class << self
8689
# Set where RailsAdmin fetches JS/CSS from, defaults to :sprockets
8790
attr_writer :asset_source
8891

89-
# Finish initialization by executing deferred configuration blocks
90-
def initialize!
91-
return if @initializing
92+
# Finish initialization by executing deferred non-model configuration blocks
93+
def initialize_core!
94+
return if @initializing_core
9295

93-
@initializing = true
94-
@deferred_blocks.each { |block| block.call(self) }
95-
@deferred_blocks.clear
96-
@initialized = true
96+
@initializing_core = true
97+
@deferred_core_blocks.each { |block| block.call(self) }
98+
@deferred_core_blocks.clear
99+
@initialized_core = true
97100
end
98101

99-
# Evaluate the given block either immediately or lazily, based on initialization status.
100-
def apply(&block)
101-
if @initialized
102+
# Evaluate the given non-model block either immediately or lazily, based on initialization status.
103+
def apply_core(&block)
104+
if @initialized_core
102105
yield(self)
103106
else
104-
@deferred_blocks << block
107+
@deferred_core_blocks << block
108+
end
109+
end
110+
111+
# Finish initialization by executing deferred model configuration blocks
112+
def initialize_models!
113+
return if @initializing_models
114+
115+
initialize_core!
116+
@initializing_models = true
117+
@deferred_model_blocks.each { |block| block.call(self) }
118+
@deferred_model_blocks.clear
119+
@initialized_models = true
120+
end
121+
122+
# Evaluate the given model block either immediately or lazily, based on initialization status.
123+
def apply_model(&block)
124+
if @initialized_models
125+
yield(self)
126+
else
127+
@deferred_model_blocks << block
105128
end
106129
end
107130

@@ -230,7 +253,7 @@ def default_search_operator=(operator)
230253

231254
# pool of all found model names from the whole application
232255
def models_pool
233-
initialize!
256+
initialize_models!
234257
(viable_models - excluded_models.collect(&:to_s)).uniq.sort
235258
end
236259

@@ -268,13 +291,13 @@ def model(entity, &block)
268291
#
269292
# Do not defer when called without a block as the model must be returned.
270293
if block
271-
RailsAdmin::Config.apply do
294+
RailsAdmin::Config.apply_model do
272295
m = model(entity)
273296
m.instance_eval(&block) if @registry[key].abstract_model
274297
end
275298
nil
276299
else
277-
initialize!
300+
initialize_models!
278301
@registry[key] ||= RailsAdmin::Config::Model.new(entity)
279302
end
280303
end
@@ -338,8 +361,10 @@ def models
338361
#
339362
# @see RailsAdmin::Config.registry
340363
def reset
341-
@initialized = @initializing = false
342-
@deferred_blocks.clear
364+
@initialized_core = @initializing_core = false
365+
@deferred_core_blocks.clear
366+
@initialized_models = @initializing_models = false
367+
@deferred_model_blocks.clear
343368
@compact_show_view = true
344369
@browser_validations = true
345370
@authenticate = nil
@@ -380,6 +405,7 @@ def reset_model(model)
380405
def reload!
381406
reset
382407
load RailsAdmin::Engine.config.initializer_path
408+
initialize_core!
383409
end
384410

385411
# Get all models that are configured as visible sorted by their weight and label.

lib/rails_admin/engine.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,11 @@ class Engine < Rails::Engine
6868
ERROR
6969
end
7070

71+
RailsAdmin::Config.initialize_core!
72+
73+
# Force route reload, since it doesn't reflect RailsAdmin action configuration yet
74+
app.reload_routes!
75+
7176
RailsAdmin::Version.warn_with_js_version
7277
end
7378
end

spec/dummy_app/config/initializers/rails_admin.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
RailsAdmin.config do |c|
44
c.asset_source = CI_ASSET
5-
c.model 'Team' do
5+
c.model Team do
66
include_all_fields
77
field :color, :color
88
end

spec/rails_admin/config_spec.rb

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
require 'spec_helper'
44

55
RSpec.describe RailsAdmin::Config do
6+
before { RailsAdmin::Config.reset }
7+
68
describe '.included_models' do
79
it 'only uses included models' do
810
RailsAdmin.config.included_models = [Team, League]
@@ -66,6 +68,8 @@
6668
end
6769

6870
describe '.main_app_name' do
71+
before { RailsAdmin::Config.initialize_core! }
72+
6973
it 'as a default meaningful dynamic value' do
7074
expect(RailsAdmin.config.main_app_name.call).to eq(['Dummy App', 'Admin'])
7175
end
@@ -79,6 +83,8 @@
7983
end
8084

8185
describe '.authorize_with' do
86+
before { RailsAdmin::Config.initialize_core! }
87+
8288
context 'given a key for a extension with authorization' do
8389
before do
8490
RailsAdmin.add_extension(:example, ExampleModule, authorization: true)
@@ -104,6 +110,8 @@
104110
end
105111

106112
describe '.audit_with' do
113+
before { RailsAdmin::Config.initialize_core! }
114+
107115
context 'given a key for a extension with auditing' do
108116
before do
109117
RailsAdmin.add_extension(:example, ExampleModule, auditing: true)
@@ -149,6 +157,8 @@ class Version; end
149157
end
150158

151159
describe '.configure_with' do
160+
before { RailsAdmin::Config.initialize_core! }
161+
152162
context 'given a key for a extension with configuration' do
153163
before do
154164
RailsAdmin.add_extension(:example, ExampleModule, configuration: true)
@@ -174,6 +184,8 @@ class Version; end
174184
end
175185

176186
describe '.config' do
187+
before { RailsAdmin::Config.initialize_core! }
188+
177189
context '.default_search_operator' do
178190
it 'sets the default_search_operator' do
179191
RailsAdmin.config do |config|
@@ -267,6 +279,8 @@ class RecursivelyEmbedsMany
267279
end
268280

269281
describe '.parent_controller' do
282+
before { RailsAdmin::Config.initialize_core! }
283+
270284
before do
271285
class TestController < ActionController::Base; end
272286
end
@@ -305,6 +319,8 @@ class TestController < ActionController::Base; end
305319
end
306320

307321
describe '.forgery_protection_settings' do
322+
before { RailsAdmin::Config.initialize_core! }
323+
308324
it 'uses with: :exception by default' do
309325
expect(RailsAdmin.config.forgery_protection_settings).to eq(with: :exception)
310326
end
@@ -395,38 +411,39 @@ class TestController < ActionController::Base; end
395411
end
396412
end
397413

398-
describe '.apply' do
399-
subject { RailsAdmin::Config.apply(&block) }
414+
describe '.apply_core' do
415+
subject { RailsAdmin::Config.apply_core(&block) }
400416
let(:block) do
401417
proc do |config|
402418
config.model Team do
403419
register_instance_option('parameter') # an arbitrary instance method we can spy on
404420
end
405421
end
406422
end
407-
before { RailsAdmin::Config.instance_variable_set(:@initialized, false) }
408-
before { RailsAdmin::Config.instance_variable_set(:@initializing, false) }
409-
after do
410-
RailsAdmin::Config.instance_variable_set(:@initialized, true)
411-
RailsAdmin::Config.instance_variable_set(:@deferred_blocks, [])
412-
end
423+
after { RailsAdmin::Config.reset }
413424

414425
it "doesn't evaluate the block immediately" do
415426
expect_any_instance_of(RailsAdmin::Config::Model).not_to receive(:register_instance_option)
416427
subject
417428
end
418429

419-
it 'evaluates block when initialize! is finished' do
430+
it "doesn't evaluate the block when initialize_core! is finished" do
431+
expect_any_instance_of(RailsAdmin::Config::Model).not_to receive(:register_instance_option).with('parameter')
432+
subject
433+
RailsAdmin::Config.initialize_core!
434+
end
435+
436+
it 'evaluates block when initialize_models! is finished' do
420437
expect_any_instance_of(RailsAdmin::Config::Model).to receive(:register_instance_option).with('parameter')
421438
subject
422-
RailsAdmin::Config.initialize!
439+
RailsAdmin::Config.initialize_models!
423440
end
424441

425442
it 'evaluates config block only once' do
426443
expect_any_instance_of(RailsAdmin::Config::Model).to receive(:register_instance_option).once.with('parameter')
427444
subject
428-
RailsAdmin::Config.initialize!
429-
RailsAdmin::Config.initialize!
445+
RailsAdmin::Config.initialize_models!
446+
RailsAdmin::Config.initialize_models!
430447
end
431448

432449
context 'with a non-existent class' do
@@ -465,7 +482,7 @@ class TestController < ActionController::Base; end
465482
end
466483

467484
it 'does not immediately apply model configuration' do
468-
expect(RailsAdmin::Config).not_to receive(:initialize!)
485+
expect(RailsAdmin::Config).not_to receive(:initialize_models!)
469486
RailsAdmin::Config.reload!
470487
end
471488

0 commit comments

Comments
 (0)