Páginas Estáticas no Rails

2011 November 11, 01:38 h - tags: beginner rails learning

Faz tempo que não posto uma dica técnica, vou retornando aos poucos. Hoje uma dica bem simples mas que muitos ainda desconhecem.

Muitos aplicativos Rails tem seções com páginas estáticas, páginas de conteúdo como institucional, instruções, etc. Digamos que para organizar isso você tenha criado um controller chamado “Page”, assim:

1
bundle exec rails g controller Page

O problema é que eu sempre vejo algo parecido com isto no config/routes.rb

1
2
3
  match "page/hello" => "page#hello"
  match "page/help" => "page#help"
  ...

Daí no app/controllers/page_controller.rb encontro:

1
2
3
4
5
6
  def hello
  end

  def help
  end
  ...

Actions vazias de placeholder somente para renderizar páginas estáticas como app/views/page/hello.html.erb. E este exemplo tem apenas duas páginas, agora escale isso para algumas dezenas e você verá logo o code smell de um clássico efeito shotgun: múltiplos match redundantes no routes.rb e múltiplos métodos vazios no controller.

Em vez disso, uma das muitas formas de resolver esse problema é fazer simplesmente isto no arquivo config/routes.rb:

1
  get "page/:id" => "page#index", :as => :page

E no controller “Page” ter uma única action:

1
2
3
  def index
    render params[:id]
  end

Agora você pode colocar quantas views quiser em app/views/page e quando chamar http://localhost:3000/page/hello ele irá automaticamente mapear para app/views/page/hello.html.erb.

Eu disse “páginas estáticas” mas na verdade seriam “semi-estáticas” já que normalmente faríamos desta forma porque queremos que a página herde o layout principal e tudo mais. Se for para ser uma página realmente estática, fora do layout padrão do site, etc, você pode simplesmente colocar um html no diretório public.

Dá para melhorar mais isso, fazendo algumas checagens óbvias como validar se o template da página existe:

1
2
3
4
5
6
7
  def index
    if params[:id] && template_exists?(params[:id], ["page"])
      render params[:id]
    else
      redirect_to '/404.html', :status => 404
    end
  end

A dica é a mesma de sempre: se está parecendo um amontoado de copy & paste em todas as camadas, alguma coisa está definitivamente errada. Como eu disse antes, existem múltiplas maneiras para resolver essa funcionalidade, se tiverem outras melhores, não deixem de comentar.

Comments

comentários deste blog disponibilizados por Disqus