Skip to content

Commit e4ae669

Browse files
committed
Reload configuration on change in development mode
Fixes railsadminteam#2726, Fixes railsadminteam#3025
1 parent f2104b5 commit e4ae669

File tree

12 files changed

+190
-177
lines changed

12 files changed

+190
-177
lines changed

config/initializers/active_record_extensions.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
module ActiveRecord
33
class Base
44
def self.rails_admin(&block)
5-
RailsAdmin.config(self, &block)
5+
RailsAdmin.config do |config|
6+
config.model(self, &block)
7+
end
68
end
79

810
def rails_admin_default_object_label_method

lib/rails_admin.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ def self.config(entity = nil, &block)
2727
if entity
2828
RailsAdmin::Config.model(entity, &block)
2929
elsif block_given?
30-
block.call(RailsAdmin::Config)
30+
RailsAdmin::Config.apply(&block)
3131
else
3232
RailsAdmin::Config
3333
end

lib/rails_admin/abstract_model.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ def all(adapter = nil)
1919
def new(m)
2020
m = m.constantize unless m.is_a?(Class)
2121
(am = old_new(m)).model && am.adapter ? am : nil
22-
rescue LoadError, NameError
22+
rescue *([LoadError, NameError] + (defined?(ActiveRecord) ? ['ActiveRecord::NoDatabaseError'.constantize] : []))
2323
puts "[RailsAdmin] Could not load model #{m}, assuming model is non existing. (#{$ERROR_INFO})" unless Rails.env.test?
2424
nil
2525
end

lib/rails_admin/adapters/mongoid/extension.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ module Extension
99
self.nested_attributes_options = {}
1010
class << self
1111
def rails_admin(&block)
12-
RailsAdmin.config(self, &block)
12+
RailsAdmin.config do |config|
13+
config.model(self, &block)
14+
end
1315
end
1416

1517
alias_method :accepts_nested_attributes_for_without_rails_admin, :accepts_nested_attributes_for

lib/rails_admin/config.rb

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
require 'rails_admin/config/lazy_model'
1+
require 'rails_admin/config/model'
22
require 'rails_admin/config/sections/list'
33
require 'active_support/core_ext/module/attribute_accessors'
44

@@ -20,6 +20,10 @@ module Config
2020

2121
DEFAULT_CURRENT_USER = proc {}
2222

23+
# Variables to track initialization process
24+
@initialized = false
25+
@deferred_blocks = []
26+
2327
class << self
2428
# Application title, can be an array of two elements
2529
attr_accessor :main_app_name
@@ -82,6 +86,22 @@ class << self
8286
attr_accessor :navigation_static_links
8387
attr_accessor :navigation_static_label
8488

89+
# Finish initialization by executing deferred configuration blocks
90+
def initialize!
91+
@deferred_blocks.each { |block| block.call(self) }
92+
@deferred_blocks.clear
93+
@initialized = true
94+
end
95+
96+
# Evaluate the given block either immediately or lazily, based on initialization status.
97+
def apply(&block)
98+
if @initialized
99+
block.call(self)
100+
else
101+
@deferred_blocks << block
102+
end
103+
end
104+
85105
# Setup authentication to be run as a before filter
86106
# This is run inside the controller instance so you can setup any authentication you need to
87107
#
@@ -235,8 +255,8 @@ def model(entity, &block)
235255
end
236256
end
237257

238-
@registry[key] ||= RailsAdmin::Config::LazyModel.new(entity)
239-
@registry[key].add_deferred_block(&block) if block
258+
@registry[key] ||= RailsAdmin::Config::Model.new(entity)
259+
@registry[key].instance_eval(&block) if block && @registry[key].abstract_model
240260
@registry[key]
241261
end
242262

@@ -311,10 +331,17 @@ def reset_all_models
311331
@registry = {}
312332
end
313333

334+
# Perform reset, then load RailsAdmin initializer again
335+
def reload!
336+
@initialized = false
337+
reset
338+
load RailsAdmin::Engine.config.initializer_path
339+
initialize!
340+
end
341+
314342
# Get all models that are configured as visible sorted by their weight and label.
315343
#
316344
# @see RailsAdmin::Config::Hideable
317-
318345
def visible_models(bindings)
319346
visible_models_with_bindings(bindings).sort do |a, b|
320347
if (weight_order = a.weight <=> b.weight) == 0

lib/rails_admin/config/lazy_model.rb

Lines changed: 0 additions & 68 deletions
This file was deleted.

lib/rails_admin/engine.rb

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,23 @@ class Engine < Rails::Engine
2424
app.config.middleware.use Rack::Pjax
2525
end
2626

27-
initializer 'RailsAdmin reload config in development' do
28-
if Rails.application.config.cache_classes
27+
initializer 'RailsAdmin reload config in development' do |app|
28+
config.initializer_path = app.root.join('config/initializers/rails_admin.rb')
29+
30+
unless Rails.application.config.cache_classes
2931
ActiveSupport::Reloader.before_class_unload do
30-
RailsAdmin::Config.reset_all_models
32+
RailsAdmin::Config.reload!
33+
end
34+
35+
reloader = app.config.file_watcher.new([config.initializer_path], []) do
36+
# Do nothing, ActiveSupport::Reloader will trigger class_unload! anyway
3137
end
38+
39+
app.reloaders << reloader
40+
app.reloader.to_run do
41+
reloader.execute_if_updated { require_unload_lock! }
42+
end
43+
reloader.execute
3244
end
3345
end
3446

@@ -57,6 +69,8 @@ class Engine < Rails::Engine
5769
to config/application.rb.
5870
EOM
5971
end
72+
73+
RailsAdmin::Config.initialize!
6074
end
6175
end
6276
end

spec/rails_admin/abstract_model_spec.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,18 @@
1111
end
1212
end
1313

14+
describe '.new' do
15+
context 'on ActiveRecord::NoDatabaseError', active_record: true do
16+
before do
17+
expect(WithoutTable).to receive(:table_exists?).and_raise(ActiveRecord::NoDatabaseError)
18+
end
19+
20+
it 'does not raise error and returns nil' do
21+
expect(RailsAdmin::AbstractModel.new('WithoutTable')).to eq nil
22+
end
23+
end
24+
end
25+
1426
describe '#to_s' do
1527
it 'returns model\'s name' do
1628
expect(RailsAdmin::AbstractModel.new(Cms::BasicPage).to_s).to eq Cms::BasicPage.to_s

spec/rails_admin/config/has_fields_spec.rb

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,24 @@
5151

5252
expect(RailsAdmin.config(Team).fields.map(&:name)).to eql(original_fields_order)
5353
end
54+
55+
describe '#_fields' do
56+
let(:config) { RailsAdmin.config(Team) }
57+
before do
58+
RailsAdmin.config(Team) do
59+
field :id
60+
field :wins, :boolean
61+
end
62+
end
63+
64+
it "does not cause FrozenError by changing exiting field's tye" do
65+
# Reference the fields for readonly
66+
config.edit.send(:_fields, true)
67+
68+
RailsAdmin.config(Team) do
69+
field :wins, :integer
70+
end
71+
expect(config.fields.map(&:name)).to match_array %i(id wins)
72+
end
73+
end
5474
end

spec/rails_admin/config/lazy_model_spec.rb

Lines changed: 0 additions & 45 deletions
This file was deleted.

0 commit comments

Comments
 (0)