RubyOnBr logo

Reaproveitando Controllers

Quando se fala em herança ou reuso no Rails, geralmente os desenvolvedores pensam em aproveitamento dos modelos de dados, sendo que STI, ou single table inheritance, é uma das formas mais comuns.

Controllers, porém, podem ser tranqüilamente reaproveitados. Na verdade, o Rails já usa herança por padrão, já que todos controllers em uma aplicação são derivados da classe ApplicationController. Isso é o que, por exemplo, permite usar filtros automaticamente em toda aplicação se os mesmos forem declarados nesse primeiro controller.

Existem algumas outras situações, entrentanto, em que reusar um outro controller específico pode ser necessário. E, com alguns pequenos cuidados, é possível usar herança ou aproveitar um controller qualquer de algumas maneiras interessantes para facilitar o desenvolvimento e aumentar a produtividade.

Uma dessas situações, por exemplo, é separar funcionalidade entre a área administrativa e a área pública de uma aplicação. Ao invés de ficar especificando condições ou usando variáveis de sessão para distingüir entre duas áreas, especificar uma cadeia de herança por ser uma solução mais simples e elegante.

Digamos que você tenha criado um aplicação simples e tenha alguns controllers para a área pública e alguns para a administração. Você poderia ter algo como no seu arquivo application.rb:

application.rb

E dois diferentes controllers em seus arquivos específicos:

private_controller.rb

public_controller.rb

O exemplo acima é bem simples, mas já dá uma idéia do que seria posível fazer. Funcionalidades realmente genéricas da aplicação ficariam na classe ApplicationController enquanto que funcionalidade mais específica de cada área poderia ficar nas classes bases BasePrivateController e BasePublicController.

É possível inclusive pensar em uma completa hierarquia de controllers para lidar com situações específicas como múltiplas áreas públicas e privadas. Obviamente, nesse caso seria mais interessante pensar em definir esses controllers específicos em seus próprios arquivos e carregá-los diretamente.

Ações também podem ser reaproveitadas em uma estrutura como a acima com bastante facilidade. Basta ter o pequeno cuidado de usar render com o parâmetro :template para evitar que a ação busque os arquivos no local incorreto.

Uma outra possibilidade, especialmente útil para áreas que compartilham muita funcionalidade, é usar um controller genérico para lidar com múltiplas classes de dados. Seria uma espécie de scaffolding, mas customizado para necessidades específicas da aplicação. Digamos que uma série de cadastros compartilhe operações básicas. Poderíamos ter um controller assim:

Um controller para lidar com o modelo de dados de usuários ficaria simplesmente assim:

Uma tentação acima poderia ser mudar o método get_model para um variável de classe. Considerando o modo como o Ruby lida com esse tipo de variável e o modo como o Rails carrega classes em produção, é fácil perceber que isso causaria uma série de erros estranhos e difíceis de detectar na aplicação.

Usando o método acima, seria fácil customizar os modelos de dados para operarem com uma interface de métodos reaproveitáveis, especialmente considerando as características de meta-programação do Ruby.

Obviamente, as duas técnicas acima servem para situações específicas e não devem ser consideradas para uma prática global em toda e qualquer aplicação. São usos do Rails que podem ajudar o desenvolvimento de aplicação e aumentar a produtividade, mas não devem servir de muletas para o desenvolvedor.

Espero que vocês tenham aprendido alguma coisa de útil. Se não, quem sabe no próximo artigo? :-D

Ronaldo Ferraz

Comente aqui

Todos os diretos reservados a RubyOnBr. Copyright RubyOnBr .
This site is powered by Radiant CMS.