Controllers e rotas REST
resources gera 7 rotas de uma vez — entender as 7 evita reinventar rota fora do padrão REST.
resources :produtos em routes.rb gera 7 rotas de uma vez, cada uma mapeada pra uma action do controller. Saber essas 7 de cor evita inventar rota fora do padrão REST — o que quase sempre é sinal de que falta uma action, não de que o REST não serve pro caso.
Verbo URL Action Uso
GET /produtos index listar todos
GET /produtos/new new (só em app c/ view — API não usa)
POST /produtos create criar um novo
GET /produtos/:id show mostrar um específico
GET /produtos/:id/edit edit (só em app c/ view — API não usa)
PATCH /produtos/:id update atualizar parcialmente
DELETE /produtos/:id destroy removerNuma API, new/edit não fazem sentido (não existe formulário HTML pra "editar") — por isso o gerador com --api já não inclui essas duas.
O controller — uma action por rota
class ProdutosController < ApplicationController
before_action :set_produto, only: [:show, :update, :destroy]
def index
render json: Produto.all
end
def show
render json: @produto
end
def create
produto = Produto.new(produto_params)
if produto.save
render json: produto, status: :created
else
render json: { errors: produto.errors.full_messages }, status: :unprocessable_entity
end
end
def update
if @produto.update(produto_params)
render json: @produto
else
render json: { errors: @produto.errors.full_messages }, status: :unprocessable_entity
end
end
def destroy
@produto.destroy
head :no_content
end
private
def set_produto
@produto = Produto.find(params[:id])
end
def produto_params
params.require(:produto).permit(:nome, :preco)
end
endbefore_action :set_produto, only: [...] evita repetir Produto.find(params[:id]) em 3 actions — roda antes delas, deixando @produto pronto. E cada branch de erro devolve um status HTTP correto (422 pra validação falhando, 204 pra delete sem corpo) — o código de status é parte do contrato da API, não detalhe.
Exercício
Se Produto.find(params[:id]) não achar o registro, o Rails levanta ActiveRecord::RecordNotFound. Sem tratamento nenhum, isso vira erro 500. Que status HTTP deveria ser esse, e onde você trataria isso pra não repetir em cada controller?