How to implement an Abstract Controller that executes actions implemented in concrete controllers, depending on the variables passed via params?

1

I need an abstract controller to redirect the execution of the "create" and "show" actions implemented in modules, according to values passed through params, eg:

    class Indicator::AbstractController < ApplicationController

    # é aqui que não funciona
    # sei que aqui é a definição da classe, portanto não dá para 
    # utilizar as variáveis de instancia

      include ConcreteController1 if params[:resource_type_id].eql?(1)
      include ConcreteController2 if params[:resource_type_id].eql?(2)


      #não implementa method/action create
      #não implementa method/action show

      # já tentei implementar as actions create e view e redirecionar a execução para 
      # os módulos concretos, mas não consegui.
    end

    Module ConcreteController1
      def create
        # metodo de criação especial para o controller1
      end

      def show
        # view especial para o controller1
      end
    end


    Module ConcreteController2
      def create
        # metodo de criação especial para o controller2
      end

      def show
        # view especial para o controller2
      end
    end

I've tried converting the modules into classes ConcreteController < ApplicationController and redirection via routes but also had difficulties because the number of concrete controllers is variable.

We are in a legacy application in Rails 3.2

    
asked by anonymous 13.10.2017 / 12:57

3 answers

2

Maybe you can do this by using constraints on the route
link
Something like:

get '/users/{id}', action: 'show' controller: "my_controller1", constraints: lambda { |request| request[:resource_type_id] == 1 }  
get '/users/{id}', action: 'show' controller: "my_controller2", constraints: lambda { |request| request[:resource_type_id] == 2 }  

Code not tested (syntax probably wrong) but the idea is this

    
14.10.2017 / 03:17
1

In your case, I would use a class responsible for knowing how to redirect to the desired action from the parameters.

concrete_action = ConcreteAction.new( params )
concrete_action.execute_create
concrete_action.execute_show

in your controller would be

class Indicator::AbstractController < ApplicationController

def create
  concrete_action = ConcreteAction.new( params )
  resultado = concrete_action.execute_create
  redirect_to 'algum path'
end

end

However, a good suggestion is to look into Use Case Controller and other architectural patterns. A slightly different approach to what you're trying, but I think it will help you too.

  • Use Case Controller - Craig Larman
  • link
  • GRASP PATTERNS
13.10.2017 / 17:19
0

Dude, I do not know if you can do what you want it that way. You may even have inheritance in the controllers, but not in this way you described above.

In fact to give more concrete help I needed to know what your problem is. Perhaps the dynamic controllers are not the solution to the problem.

    
13.10.2017 / 17:13