Em desenvolvimento de software, um framework é uma abstração que provê um esqueleto de aplicação genérica. Essa aplicação genérica provê funcionalidades para evitar retrabalho comum à maior parte das aplicações, como a configuração do banco de dados e criação de tabelas/CRUD’s, por exemplo. Ao contrário das bibliotecas, na utilização de um framework há a inversão de controle, pois o fluxo da aplicação é feito pelo framework, não pelo programador.
Em Ruby on Rails, a geração dos arquivos MVC (Model-View-Controller) e dos assets é feita usualmente utilizando o gerador padrão do framework. Como o fluxo de controle é determinado pelo framework (convention over configuration), ele assume uma série de padrões quanto à geração desses arquivos. Por exemplo, o formato de arquivos é o coffee script, arquivos css no formato .scss e arquivos de template HTML em .erb. Ao longo de um projeto mais complexo e que possui um número relevante de entidades, torna-se viável sobrescrever esse comportamento padrão na geração dos arquivos.
Você pode fazer essa configuração no arquivo config/application.rb. Por exemplo, para alterar o formato padrão de script para js e evitar a geração de arquivos css:
1 2 3 4 |
config.generators do |g| g.javascript_engine = :js g.stylesheets false end |
Outros exemplos de costumização na geração podem ser vistos aqui e a referência completa pode ser consultada no guia de configuração do Rails na seção 3.3. Mais além do que configurações básicas da geração, muitas vezes é desejável customizar também o template dos arquivos gerados. A partir do Rails 3.0, é possível fazer a sobrescrita dos templates dos arquivos da view e do controller, por exemplo. Os arquivos de template da view e do controller devem ser colocados nas pastas “/lib/templates/erb/scaffold” e “/lib/templates/rails/scaffold_controller”, respectivamente (possivelmente as pastas não existem e devem ser criadas).
Você pode copiar os templates que o Rails utiliza originalmente para geração e alterá-los conforme sua necessidade. A forma mais fácil de encontrar esses arquivos é localizando a pasta da gem railties, através do comando “bundle show railties”. O arquivo de template do controller pode ser localizado em “lib/rails/generators/rails/scaffold_controller/templates/controller.rb” e os arquivos da view em “lib/rails/generators/erb/scaffold/templates”. Você pode copiar os arquivos que desejar sobrescrever para a pasta correspondente no projeto.
Apesar de possuir uma sintaxe com funções próprias, o código dos templates é bem intuitivo. Em um exemplo de customização, suponha que você está utilizando a gem chosen-select e deseja que, sempre que gerar um atributo de associação, ele já possua a classe “chosen-select” no formulário. Alterando o código original da partial form, o template ficaria como segue:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
<%%= form_for(<%= singular_table_name %>) do |f| %> <%% if <%= singular_table_name %>.errors.any? %> <div id="error_explanation"> <h2><%%= pluralize(<%= singular_table_name %>.errors.count, "error") %> prohibited this <%= singular_table_name %> from being saved:</h2> <ul> <%% <%= singular_table_name %>.errors.full_messages.each do |message| %> <li><%%= message %></li> <%% end %> </ul> </div> <%% end %> <% attributes.each do |attribute| -%> <div class="field"> <% if attribute.password_digest? -%> <%%= f.label :password %> <%%= f.password_field :password %> </div> <div class="field"> <%%= f.label :password_confirmation %> <%%= f.password_field :password_confirmation %> <% elsif attribute.reference? %> <%%= f.label :<%= attribute.column_name %> %> <%%= f.select :<%= attribute.column_name %>, <%= attribute.name.camelize %>.all, {}, { :class => 'chosen-select' } %> <% else %> <%%= f.label :<%= attribute.column_name %> %> <%%= f.<%= attribute.field_type %> :<%= attribute.column_name %> %> <% end -%> </div> <% end -%> <div class="actions"> <%%= f.submit %> </div> <%% end %> |
As linha 24-26 foram adicionadas ao código original para verificar se o atributo é uma associação e, para esse caso, exibir um select com a classe desejada. Não é necessário nenhuma alteração adicional para que as próximas views sejam geradas nesse formato. Em um post futuro, vou demonstrar uma forma mais avançada de customizar a geração dos scaffolds através da criação de um gerador próprio, permitindo um maior controle e possibilitando por exemplo a criação de arquivos adicionais aos gerados por padrão. Quaisquer dúvidas ou sugestões, utilize o campo de comentários ou entre em contato!
2 Comentários
Sannytet
12 de dezembro de 2018 at 01:28Nice posts! 🙂
___
Sanny
Daniel
29 de julho de 2019 at 11:47Shoow cara, tudo que eu precisava!