Skip to content

Commit

Permalink
Reload configuration on change in development mode
Browse files Browse the repository at this point in the history
Fixes #2726, Fixes #3025
  • Loading branch information
mshibuya committed Oct 17, 2021
1 parent f2104b5 commit e4ae669
Show file tree
Hide file tree
Showing 12 changed files with 190 additions and 177 deletions.
4 changes: 3 additions & 1 deletion config/initializers/active_record_extensions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
module ActiveRecord
class Base
def self.rails_admin(&block)
RailsAdmin.config(self, &block)
RailsAdmin.config do |config|
config.model(self, &block)
end
end

def rails_admin_default_object_label_method
Expand Down
2 changes: 1 addition & 1 deletion lib/rails_admin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def self.config(entity = nil, &block)
if entity
RailsAdmin::Config.model(entity, &block)
elsif block_given?
block.call(RailsAdmin::Config)
RailsAdmin::Config.apply(&block)
else
RailsAdmin::Config
end
Expand Down
2 changes: 1 addition & 1 deletion lib/rails_admin/abstract_model.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def all(adapter = nil)
def new(m)
m = m.constantize unless m.is_a?(Class)
(am = old_new(m)).model && am.adapter ? am : nil
rescue LoadError, NameError
rescue *([LoadError, NameError] + (defined?(ActiveRecord) ? ['ActiveRecord::NoDatabaseError'.constantize] : []))
puts "[RailsAdmin] Could not load model #{m}, assuming model is non existing. (#{$ERROR_INFO})" unless Rails.env.test?
nil
end
Expand Down
4 changes: 3 additions & 1 deletion lib/rails_admin/adapters/mongoid/extension.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ module Extension
self.nested_attributes_options = {}
class << self
def rails_admin(&block)
RailsAdmin.config(self, &block)
RailsAdmin.config do |config|
config.model(self, &block)
end
end

alias_method :accepts_nested_attributes_for_without_rails_admin, :accepts_nested_attributes_for
Expand Down
35 changes: 31 additions & 4 deletions lib/rails_admin/config.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
require 'rails_admin/config/lazy_model'
require 'rails_admin/config/model'
require 'rails_admin/config/sections/list'
require 'active_support/core_ext/module/attribute_accessors'

Expand All @@ -20,6 +20,10 @@ module Config

DEFAULT_CURRENT_USER = proc {}

# Variables to track initialization process
@initialized = false
@deferred_blocks = []

class << self
# Application title, can be an array of two elements
attr_accessor :main_app_name
Expand Down Expand Up @@ -82,6 +86,22 @@ class << self
attr_accessor :navigation_static_links
attr_accessor :navigation_static_label

# Finish initialization by executing deferred configuration blocks
def initialize!
@deferred_blocks.each { |block| block.call(self) }
@deferred_blocks.clear
@initialized = true
end

# Evaluate the given block either immediately or lazily, based on initialization status.
def apply(&block)
if @initialized
block.call(self)
else
@deferred_blocks << block
end
end

# Setup authentication to be run as a before filter
# This is run inside the controller instance so you can setup any authentication you need to
#
Expand Down Expand Up @@ -235,8 +255,8 @@ def model(entity, &block)
end
end

@registry[key] ||= RailsAdmin::Config::LazyModel.new(entity)
@registry[key].add_deferred_block(&block) if block
@registry[key] ||= RailsAdmin::Config::Model.new(entity)
@registry[key].instance_eval(&block) if block && @registry[key].abstract_model
@registry[key]
end

Expand Down Expand Up @@ -311,10 +331,17 @@ def reset_all_models
@registry = {}
end

# Perform reset, then load RailsAdmin initializer again
def reload!
@initialized = false
reset
load RailsAdmin::Engine.config.initializer_path
initialize!
end

# Get all models that are configured as visible sorted by their weight and label.
#
# @see RailsAdmin::Config::Hideable

def visible_models(bindings)
visible_models_with_bindings(bindings).sort do |a, b|
if (weight_order = a.weight <=> b.weight) == 0
Expand Down
68 changes: 0 additions & 68 deletions lib/rails_admin/config/lazy_model.rb

This file was deleted.

20 changes: 17 additions & 3 deletions lib/rails_admin/engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,23 @@ class Engine < Rails::Engine
app.config.middleware.use Rack::Pjax
end

initializer 'RailsAdmin reload config in development' do
if Rails.application.config.cache_classes
initializer 'RailsAdmin reload config in development' do |app|
config.initializer_path = app.root.join('config/initializers/rails_admin.rb')

unless Rails.application.config.cache_classes
ActiveSupport::Reloader.before_class_unload do
RailsAdmin::Config.reset_all_models
RailsAdmin::Config.reload!
end

reloader = app.config.file_watcher.new([config.initializer_path], []) do
# Do nothing, ActiveSupport::Reloader will trigger class_unload! anyway
end

app.reloaders << reloader
app.reloader.to_run do
reloader.execute_if_updated { require_unload_lock! }
end
reloader.execute
end
end

Expand Down Expand Up @@ -57,6 +69,8 @@ class Engine < Rails::Engine
to config/application.rb.
EOM
end

RailsAdmin::Config.initialize!
end
end
end
12 changes: 12 additions & 0 deletions spec/rails_admin/abstract_model_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,18 @@
end
end

describe '.new' do
context 'on ActiveRecord::NoDatabaseError', active_record: true do
before do
expect(WithoutTable).to receive(:table_exists?).and_raise(ActiveRecord::NoDatabaseError)
end

it 'does not raise error and returns nil' do
expect(RailsAdmin::AbstractModel.new('WithoutTable')).to eq nil
end
end
end

describe '#to_s' do
it 'returns model\'s name' do
expect(RailsAdmin::AbstractModel.new(Cms::BasicPage).to_s).to eq Cms::BasicPage.to_s
Expand Down
20 changes: 20 additions & 0 deletions spec/rails_admin/config/has_fields_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,24 @@

expect(RailsAdmin.config(Team).fields.map(&:name)).to eql(original_fields_order)
end

describe '#_fields' do
let(:config) { RailsAdmin.config(Team) }
before do
RailsAdmin.config(Team) do
field :id
field :wins, :boolean
end
end

it "does not cause FrozenError by changing exiting field's tye" do
# Reference the fields for readonly
config.edit.send(:_fields, true)

RailsAdmin.config(Team) do
field :wins, :integer
end
expect(config.fields.map(&:name)).to match_array %i(id wins)
end
end
end
45 changes: 0 additions & 45 deletions spec/rails_admin/config/lazy_model_spec.rb

This file was deleted.

Loading

0 comments on commit e4ae669

Please sign in to comment.