Skip to content

Commit

Permalink
Merge pull request #2670 from semenovDL/feature/allow_multiple_config…
Browse files Browse the repository at this point in the history
…uration_blocks

Feature/allow multiple configuration blocks
  • Loading branch information
mshibuya authored Jul 15, 2016
2 parents 12c1eaa + d324f82 commit e55bf03
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 9 deletions.
8 changes: 3 additions & 5 deletions lib/rails_admin/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -226,11 +226,9 @@ def model(entity, &block)
end
end

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

def default_hidden_fields=(fields)
Expand Down
48 changes: 44 additions & 4 deletions lib/rails_admin/config/lazy_model.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,53 @@ module Config
class LazyModel < BasicObject
def initialize(entity, &block)
@entity = entity
@deferred_block = block
@deferred_blocks = [*block]
@existing_blocks = []
end

def add_deferred_block(&block)
@deferred_blocks << block
end

def target
unless @model
@model = ::RailsAdmin::Config::Model.new(@entity)
@model.instance_eval(&@deferred_block) if @deferred_block
@model ||= ::RailsAdmin::Config::Model.new(@entity)
# When evaluating multiple configuration blocks, the order of
# execution is important. As one would expect (in my opinion),
# options defined within a resource should take precedence over
# more general options defined in an initializer. This way,
# general settings for a number of resources could be specified
# in the initializer, while models could override these settings
# later, if required.
#
# CAVEAT: It cannot be guaranteed that blocks defined in an initializer
# will be loaded (and adde to @deferred_blocks) first. For instance, if
# the initializer references a model class before defining
# a RailsAdmin configuration block, the configuration from the
# resource will get added to @deferred_blocks first:
#
# # app/models/some_model.rb
# class SomeModel
# rails_admin do
# :
# end
# end
#
# # config/initializers/rails_admin.rb
# model = 'SomeModel'.constantize # blocks from SomeModel get loaded
# model.config model do # blocks from initializer gets loaded
# :
# end
#
# Thus, sort all blocks to excute for a resource by Proc.source_path,
# to guarantee that blocks from 'config/initializers' evaluate before
# blocks defined within a model class.
unless @deferred_blocks.empty?
@existing_blocks += @deferred_blocks
@existing_blocks.
partition { |block| block.source_location.first =~ %r{config\/initializers} }.
flatten.
each { |block| @model.instance_eval(&block) }
@deferred_blocks = []
end
@model
end
Expand Down
41 changes: 41 additions & 0 deletions spec/rails_admin/config_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,47 @@ class RecursivelyEmbedsMany
expect(RailsAdmin.config.parent_controller).to eq 'TestController'
end
end

describe '.model' do
let(:fields) { described_class.model(Team).fields }
before do
described_class.model Team do
field :players do
visible false
end
end
end
context 'when model expanded' do
before do
described_class.model(Team) do
field :fans
end
end
it 'execute all passed blocks' do
expect(fields.map(&:name)).to match_array %i(players fans)
end
end
context 'when expand redefine behavior' do
before do
described_class.model Team do
field :players
end
end
it 'execute all passed blocks' do
expect(fields.find { |f| f.name == :players }.visible).to be true
end
end
context 'when model expanded in config' do
let(:block) { proc { field :players } }
before do
allow(block).to receive(:source_location).and_return(['config/initializers/rails_admin.rb'])
described_class.model(Team, &block)
end
it 'executes first' do
expect(fields.find { |f| f.name == :players }.visible).to be false
end
end
end
end

module ExampleModule
Expand Down

0 comments on commit e55bf03

Please sign in to comment.