Controller em Rails Com respond_to e respond_with

Com o Rails 3 veio uma excelente novidade que é o uso do respond_to com respond_with, que se eu não me engano essa ideia veio do Merb, onde acabou deixando o controller um pouco mais enxuto, e também trazendo mais perfomance eliminando blocos necessários.

Então ao gerar um scaffold o Rails monta um controller da seguinte forma:

1
2
3
4
5
6
7
8
9
10
11
12
class DocumentsController < ApplicationController
  # GET /documents
  # GET /documents.xml
  def index
    @documents = Document.all

    respond_to do |format|
      format.html # index.html.erb
      format.xml  { render :xml => @documents }
    end
  end
end

Eu eliminei as outras actions, mas sabemos que exite a repetição do bloco respond_to em todas as outras actions.

Normalmente a index responde a vários formatos, mudando o nosso controller para trabalhar com respond_to e respond_with, podemos retirar o bloco de todas as nossas actions, abaixo um exemplo:

1
2
3
4
5
6
7
8
9
10
11
12
13
class DocumentsController < ApplicationController
  respond_to :html, :js, :xml
  def index
    @documents = Document.all
  end

  def create
    @document = Document.new(params[:document])
    @document.slug = SlugGenerator.new(@document.name).slugify!
    flash[:notice] = 'Document was successfully created.' if @document.save
    respond_with(@document)
  end
end

Também existe esse forma de implementar a index:

1
2
3
4
5
6
7
8
class DocumentsController < ApplicationController

  def index
    @documents = Document.all
    respond_with(@documents, :to => [ :html, :xml, :json, :atom ])
  end

end

No exemplo que tem a action create temos respond_with(@document), onde a action ira redirecionar para a action show do objeto, se você quer que ele siga para outra action é so adicionar :location => url

1
2
3
4
5
6
def create
    @document = Document.new(params[:document])
    @document.slug = SlugGenerator.new(@document.name).slugify!
    flash[:notice] = 'Document was successfully created.' if @document.save
    respond_with(@document, location => documents_url )
end

É assim que mais ou menos fica um simples controller meu em Rails:

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
38
39
40
41
# encoding: utf-8
class ColorsController < AdminController

  respond_to :html

  def index
    @colors = Color.all
  end

  def show
    @color = Color.find_by_slug(params[:id])
  end

  def new
    @color = Color.new
  end

  def edit
    @color = Color.find_by_slug(params[:id])
  end

  def create
    @color = Color.new(params[:color])
    @color.slug = SlugGenerator.new(@color.name).slugify!
    flash[:notice] = 'Color was successfully created.' if @color.save
    respond_with(@color)
  end

  def update
    @color = Color.find_by_slug(params[:id])
    @color.slug = SlugGenerator.new(@color.name).slugify!
    flash[:notice] = 'Color was successfully updated.' if @color.update_attributes(params[:color])
    respond_with(@color)
  end

  def destroy
    flash[:notice] = 'Color was successfully deleted.' if Color.find_by_slug(params[:id]).destroy
    respond_with(@color, :location => colors_url)
  end

end

Simples e rápido, peguei um controller já pronto nesse último exemplo lol.

Comments