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

Asked

Viewed 141 times

1

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

    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 have tried to convert the modules into Concretecontroller < Applicationcontroller classes and redirect via Routes but also had difficulties because the number of concrete controllers is variable.

We are in a legacy application on Rails 3.2

3 answers

2

Maybe you can do this using constraints on the route
http://guides.rubyonrails.org/routing.html#Advanced-constraints
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 }  

Untested code (probably wrong syntax) but the idea is this

1

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

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

on 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 for Use Case Controller and other architectural patterns. A slightly different approach than what you’re trying, but I think it’ll help you too.

0

Man, I don’t know if you can do what you want like that. You may have inheritance in the controllers, but not in the way you described above.

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

Browser other questions tagged

You are not signed in. Login or sign up in order to post.