class TasksController < ApplicationController
def index
@tasks = Task.all
!
respond_to do |format|
format.html
format.xml { render xml: @tasks }
format.json { render json: @tasks }
end
end
end
Slide 4
Slide 4 text
Para renderizar cada formato, basta
especificar o parâmetro :format.
Slide 5
Slide 5 text
$ rake routes
Prefix Verb URI Pattern Controller#Action
root GET / site#index
tasks GET /tasks(.:format) tasks#index
POST /tasks(.:format) tasks#create
new_task GET /tasks/new(.:format) tasks#new
edit_task GET /tasks/:id/edit(.:format) tasks#edit
task GET /tasks/:id(.:format) tasks#show
PATCH /tasks/:id(.:format) tasks#update
PUT /tasks/:id(.:format) tasks#update
DELETE /tasks/:id(.:format) tasks#destroy
Slide 6
Slide 6 text
O formato pode ser especificado para
cada uma das rotas que você definiu.
Slide 7
Slide 7 text
/tasks.json
/tasks?format=json
Slide 8
Slide 8 text
À partir do Rails 3 você pode otimizar
o processo de content negotiation.
Slide 9
Slide 9 text
class TasksController < ApplicationController
respond_to :html, :json, :xml
!
def index
@tasks = Task.all
respond_with(@tasks)
end
end
Slide 10
Slide 10 text
Você pode acessar e definir explicitamente
o formato de uma requisição.
Slide 11
Slide 11 text
request.format
request.format = :json
Slide 12
Slide 12 text
Você pode criar responders personalizados que
alteram o comportamento padrão do Rails.
Slide 13
Slide 13 text
No content
Slide 14
Slide 14 text
No content
Slide 15
Slide 15 text
class TaskCreateResponder < ActionController::Responder
delegate :t, :flash, to: :controller
def to_html
if resource.new_record?
flash.notice = t('flash.tasks.create.notice')
else
flash.alert = resource.errors.full_messages
.to_sentence
end
!
redirect_to navigation_location
end
end
Slide 16
Slide 16 text
Para usar um responder,
especifique a opção :responder.
Slide 17
Slide 17 text
class TasksController < ApplicationController
respond_to :html, :json
!
def create
@task = Task.create(task_params)
respond_with @task,
location: tasks_path,
responder: TaskCreateResponder
end
end
Slide 18
Slide 18 text
Variants
Slide 19
Slide 19 text
O Rails Variants permite criar uma especialização
para o formato que está sendo renderizado.
Slide 20
Slide 20 text
A primeira ideia que vem à cabeça é renderizar um
template específico para dispositivos móveis.
Slide 21
Slide 21 text
class ApplicationController < ActionController::Base
before_action :set_variant
!
private
!
def set_variant
request.variant = :tablet if browser.tablet?
request.variant = :mobile if browser.mobile?
end
end
Slide 22
Slide 22 text
http://fnando.me/14l
Slide 23
Slide 23 text
Caso uma dessas condições seja satisfeita, o
template para aquela variante será usado.
respond_to do |format|
format.html do |variant|
variant.none(&block)
variant.tablet(&block)
variant.mobile(&block)
end
!
format.json
end
Slide 27
Slide 27 text
Todos os exemplos de variantes são sempre
baseados em detecção de dispositivos.
Slide 28
Slide 28 text
Mas variantes podem ser usadas para
abstrair a lógica de renderização.
Slide 29
Slide 29 text
No content
Slide 30
Slide 30 text
User#security_mode
none, card, sms, totp
Slide 31
Slide 31 text
class SecurityModeController < ApplicationController
def edit
request.variant = SecurityMode.fetch(params[:security_mode])
!
respond_to do |format|
format.html do |variant|
variant.none
variant.card { initialize_card_security_mode }
variant.sms { initialize_sms_security_mod }
variant.totp { initialize_totp_security_mode }
end
end
end
end
A inicialização dos objetos necessários para
renderizar a view pode ser feita dinamicamente.
Slide 34
Slide 34 text
class SecurityModeController < ApplicationController
def edit
security_mode = SecurityMode.fetch(params[:security_mode])
request.variant = security_mode
!
initializer = "initialize_#{security_mode}_security_mode"
send(initialize) if respond_to?(initializer, true)
end
end
Slide 35
Slide 35 text
Instancie apenas um objeto no controller.
Sandi Metz, http://fnando.me/14v
Slide 36
Slide 36 text
class Dashboard
def initialize(user)
@user = user
end
!
def new_status
@new_status ||= Status.new
end
!
def statuses
Status.for(user)
end
!
def notifications
@notifications ||= user.notifications
end
!
private
!
attr_reader :user
end
Slide 37
Slide 37 text
class DashboardsController < ApplicationController
before_filter :authorize
!
def show
@dashboard = Dashboard.new(current_user)
end
end