diff --git a/.rubocop.yml b/.rubocop.yml index dfaaa11708..f2f9a591c3 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -108,7 +108,7 @@ Metrics/BlockNesting: Metrics/ClassLength: CountComments: false - Max: 120 # TODO: Lower to 100 + Max: 132 # TODO: Lower to 100 Metrics/CyclomaticComplexity: Max: 15 # TODO: Lower to 6 diff --git a/app/controllers/rails_admin/main_controller.rb b/app/controllers/rails_admin/main_controller.rb index 4d81c67446..a6feb19e42 100644 --- a/app/controllers/rails_admin/main_controller.rb +++ b/app/controllers/rails_admin/main_controller.rb @@ -6,26 +6,11 @@ class MainController < RailsAdmin::ApplicationController layout :get_layout - before_action :get_model, except: RailsAdmin::Config::Actions.all(:root).collect(&:action_name) - before_action :get_object, only: RailsAdmin::Config::Actions.all(:member).collect(&:action_name) before_action :check_for_cancel - RailsAdmin::Config::Actions.all.each do |action| - class_eval <<-EOS, __FILE__, __LINE__ + 1 - def #{action.action_name} - action = RailsAdmin::Config::Actions.find('#{action.action_name}'.to_sym) - @authorization_adapter.try(:authorize, action.authorization_key, @abstract_model, @object) - @action = action.with({controller: self, abstract_model: @abstract_model, object: @object}) - fail(ActionNotAllowed) unless @action.enabled? - @page_name = wording_for(:title) - - instance_eval &@action.controller - end - EOS - end - def bulk_action - send(params[:bulk_action]) if params[:bulk_action].in?(RailsAdmin::Config::Actions.all(controller: self, abstract_model: @abstract_model).select(&:bulkable?).collect(&:route_fragment)) + get_model + process(params[:bulk_action]) if params[:bulk_action].in?(RailsAdmin::Config::Actions.all(controller: self, abstract_model: @abstract_model).select(&:bulkable?).collect(&:route_fragment)) end def list_entries(model_config = @model_config, auth_scope_key = :index, additional_scope = get_association_scope_from_params, pagination = !(params[:associated_collection] || params[:all] || params[:bulk_ids])) @@ -39,6 +24,38 @@ def list_entries(model_config = @model_config, auth_scope_key = :index, addition private + def action_missing(name, *_args) + action = RailsAdmin::Config::Actions.find(name.to_sym) + raise AbstractController::ActionNotFound.new("The action '#{name}' could not be found for #{self.class.name}", self, name) unless action + + get_model unless action.root? + get_object if action.member? + @authorization_adapter.try(:authorize, action.authorization_key, @abstract_model, @object) + @action = action.with({controller: self, abstract_model: @abstract_model, object: @object}) + raise(ActionNotAllowed) unless @action.enabled? + + @page_name = wording_for(:title) + + instance_eval(&@action.controller) + end + + def method_missing(name, *args, &block) + action = RailsAdmin::Config::Actions.find(name.to_sym) + if action + action_missing name, *args, &block + else + super + end + end + + def respond_to_missing?(sym, include_private) + if RailsAdmin::Config::Actions.find(name.to_sym) + true + else + super + end + end + def get_layout "rails_admin/#{request.headers['X-PJAX'] ? 'pjax' : 'application'}" end diff --git a/lib/rails_admin/config.rb b/lib/rails_admin/config.rb index 4a14c5a2d3..91f00a8bae 100644 --- a/lib/rails_admin/config.rb +++ b/lib/rails_admin/config.rb @@ -281,9 +281,12 @@ def parent_controller=(name) end end - # Returns action configuration object + # Setup actions to be used. def actions(&block) - RailsAdmin::Config::Actions.instance_eval(&block) if block + return unless block + + RailsAdmin::Config::Actions.reset + RailsAdmin::Config::Actions.instance_eval(&block) end # Returns all model configurations @@ -335,14 +338,6 @@ def reset_model(model) @registry.delete(key) end - # Reset all models configuration - # Used to clear all configurations when reloading code in development. - # @see RailsAdmin::Engine - # @see RailsAdmin::Config.registry - def reset_all_models - @registry = {} - end - # Perform reset, then load RailsAdmin initializer again def reload! @initialized = false diff --git a/lib/rails_admin/engine.rb b/lib/rails_admin/engine.rb index 5798af543d..278e6571b3 100644 --- a/lib/rails_admin/engine.rb +++ b/lib/rails_admin/engine.rb @@ -73,6 +73,9 @@ class Engine < Rails::Engine end RailsAdmin::Config.initialize! + + # Force route reload, since it doesn't reflect RailsAdmin action configuration yet + app.reload_routes! end end end diff --git a/spec/controllers/rails_admin/main_controller_spec.rb b/spec/controllers/rails_admin/main_controller_spec.rb index 296f5ee97b..a5ecd1bf3c 100644 --- a/spec/controllers/rails_admin/main_controller_spec.rb +++ b/spec/controllers/rails_admin/main_controller_spec.rb @@ -183,6 +183,13 @@ def get(action, params) end end + describe '#action_missing' do + it 'raises error when action is not found' do + expect(RailsAdmin::Config::Actions).to receive(:find).and_return(nil) + expect { get :index, model_name: 'player' }.to raise_error AbstractController::ActionNotFound + end + end + describe '#get_collection' do let(:team) { FactoryBot.create :team } let!(:player) { FactoryBot.create :player, team: team }