Os controladores de ação são o centro de um pedido da web em Rails. Eles são compostos de uma ou mais ações que são executadas em pedido e então ou num template ou redireciona para outra ação. Uma ação é definida como um método público no controlador, que estará automaticamente acessível para a web-server por Rails Routes.
Um simples controlador pode parecer com isto:
class GuestBookController < ActionController::Base
def index
@entries = Entry.find(:all)
end
def sign
Entry.create(params[:entry])
redirect_to :action => "index"
end
end
Actions, por padrão, um modelo no diretório app/views correspondendo ao nome do controlador e ação depois de executar código na ação. Por exemplo, a ação index do GuestBookController iria o modelo app/views/guestbook/index.rhtml por padrão depois de povoar a variável de instância @entries.
Diferentemente de index, a ação não sinalizará um modelo. Depois de apresentar seu propósito principal (criando uma nova entrada no Guest Book), inicia um redirecionamento. Este redireciona trabalhos retornando uma resposta externa "302 Moved" HTTP que leva o usuário para a ação index.
O index e sinal representam os dois arquétipos de ação básica usados em Controladores de Ação. Get-and-show e do-and-redirect. A maioria das ações são variações destes temas
Request
Request são processados pelo framework Action Controlador extraindo o valor da "chave de ação nos parâmetros request. Este valor devia segurar o nome da ação para ser apresentado. Uma vez que a ação foi identificada, os parâmetros request restante, a sessão (se uma está disponível), e o full request com todos os cabeçalhos HTTP ficam disponíveis para a ação por variáveis de instância. Então a ação é apresentada.
O objeto request está disponível com o request accessor e é principalmente usado por query para cabeçalhos HTTP. Estas queries são feitas acessando o hash de ambiente, como isto:
def server_ip
location = request.env["SERVER_ADDR"]
render :text => "This server hosted at #{location}"
end
Parameters
Todos os parâmetros request, se eles vêm de um GET ou POST request, ou do URL, estão disponíveis pelo método params que retorna um hash. Por exemplo, uma ação que era apresentada /weblog/list?category=All&limit=5 incluirá { "category" => "All", "limit" => 5 } em params.
É também possível construir hash de parâmetro dimensionais múltiplo especificando chaves usando parênteses, como:
<input type="text" name="post[name]" value="david">
<input type="text" name="post[address]" value="hyacintvej">
Um pedido originando-se de um form possuindo estas entradas incluirão { "post" => { "name" => "david", "address" => "hyacintvej" } }. Se a entrada de endereço foi nomeada "post[address][street]", O params teria incluído { "post" => { "address" => { "street" => "hyacintvej" } } }. Não há nenhum limite para a profundidade do alinhamento.
Sessions
As sessões permite que você armazene objetos entre pedidos. Isto é útil para objetos que não estão ainda prontos para ser persistidos, como objeto de Signup construido em um processo multi-paged, ou objetos que não muda muitos e são necessários o tempo todo, como objeto de Usuário para um sistema que exige login. A sessão não devia ser usada, porém, como um cache para objetos onde ele provavelmente podiam ser mudados. Ele normalmente trabalha demais para manter isso tudo sincronizados.
Você pode colocar objetos na sessão usando o método de sessão, que acessa um hash:
session[:person] = Person.authenticate(user_name, password)
E recuperado novamente pelo mesmo hash:
Hello #{session[:person]}
Para remover objetos da sessão, você pode remover qualquer um atribuindo uma chave única para NIL, como session[:person] = nil, ou você pode remover a sessão inteira com reset_session.
Por padrão, Seções são armazenadas no sistema de arquivo em RAILS_ROOT/tmp/sessions. Qualquer objeto pode ser colocado na sessão (desde que ele possa ser Disposto). Mas lembre que 1000 sessões ativas cada uma armazena um objeto de 50kb pode levar uma loja de 50MB no filesystem. Em outras palavras, pense cuidadosamente sobre tamanho e caching antes de recorrer para o uso da session no filesystem.
Uma alternativa para armazenar seções em disco é usar ActiveRecordStore para armazenar seções em seu banco de dados, que pode resolver problemas causados por armazenando de seções no sistema de arquivo e poder acelerar sua aplicação. Para usar ActiveRecordStore, descomente a linha:
config.action_controller.session_store = :active_record_store
no seu environment.rb e execute o rake db:sessions:create.
Responses
Cada ação resulta em uma resposta, que possui os cabeçalhos e documentos para serem enviadas para o navegador usuário. O objeto de resposta real é automaticamente gerado pelo uso de renders e redireciona e não exige nenhuma intervenção de usuário.
Renders
O controlador de ação envia conteúdo para o usuário usando um de cinco métodos de renderização. A mais versátil e comum ser a renderização de um modelo. Incluído no Action Pack no Action View, que habilita renderização de modelos de ERb. Ele é automaticamente configurado. O controlador passa por objetos para a visão atribuindo variáveis de instância:
def show
@post = Post.find(params[:id])
end
Que são então automaticamente disponível para a visão:
Title: <%= @post.title %>
Você não tem que contar com a retribuição automatizada. Especialmente ações que podiam resultar na renderização de modelos diferentes usarão os métodos de renderização manual:
def search
@results = Search.find(params[:query])
case @results
when 0 then render :action => "no_results"
when 1 then render :action => "show"
when 2..10 then render :action => "show_many"
end
end
Leia mais sobre escrever ERb e construir templates em classes/ActionView/Base.html.
Redirects
Redirects são usados para mover de uma ação até outra. Por exemplo, depois da ação create, que armazena uma entrada de blog para um banco de dados, nós poderíamos mostrar ao usuário a nova entrada. Porque nós seguimos os princípios DRY (Don‘t Repeat Yourself), nós vamos reusar (e redirecionar para) uma ação de show que presumimos já ter sido criado. O código poderia parecer com isto:
def create
@entry = Entry.new(params[:entry])
if @entry.save
# The entry was saved correctly, redirect to show
redirect_to :action => 'show', :id => @entry.id
else
# things didn't go so well, do something else
end
end
Neste caso, depois de salvar nossa nova entrada para o banco de dados, o usuário é redirecionado para o método show que é então executado.
Chamando múltiplos redirects ou renders
Uma ação devia concluir com um único render ou redirect. Tentando fazer qualquer um novamente resultará em um DoubleRenderError:
def do_something
redirect_to :action => "elsewhere"
render :action => "overthere" # raises DoubleRenderError
end
Se você precisar redirecionar na condição de algo, então não deixe de adicionar "and return" para parar a execução.
def do_something
redirect_to(:action => "elsewhere") and return if monkeys.nil?
render :action => "overthere" # won’t be called unless monkeys is nil
end