Pular para o conteúdo principal

Métodos do Controller

O Nerdify::ApplicationController fornece métodos auxiliares para manipular objetos, critérios de busca e renderização de páginas.


Métodos de Acesso a Objetos

object

Retorna o objeto atual (para show, edit, new, create, update, destroy):

def approve
object.update(status: "approved")
render json: { success: true }
end

O método automaticamente:

  • Busca o objeto por ID em show/edit/update/destroy
  • Cria uma instância nova em new/create
  • Atribui current_user e current_ability
  • Captura associações de parents (via parâmetros *_id)

objects

Retorna a coleção de objetos (para index):

def index
# objects retorna Model.accessible_by(current_ability).and(criteria)
super
end

O método automaticamente:

  • Aplica accessible_by(current_ability) para autorização
  • Aplica o scope e order_scope definidos
  • Aplica os criteria dos filtros
  • Aplica busca full-text se search_param presente

model

Retorna a classe do modelo baseado no nome do controller:

# Em Api::V1::CustomersController
model # => Customer

symbol

Retorna o símbolo do modelo:

# Em Api::V1::CustomersController
symbol # => :customer

variable

Retorna o nome da variável de instância:

# Em index
variable # => "@customers"

# Em show
variable # => "@customer"

Métodos de Critérios

criteria

Converte os parâmetros de filtro em critérios de busca MongoDB:

# Request: /customers?filters[status]=active&filters[city]=São Paulo
criteria
# => { status: "active", city: "São Paulo" }

O método automaticamente:

  • Remove parâmetros internos (_, page, action, etc)
  • Converte arrays: ["a","b"]{ "$in" => ["a","b"] }
  • Converte operadores: field.gte=10{ field: { "$gte" => 10 } }
  • Converte booleanos: "true"true
  • Adiciona critérios de parents

scope

Retorna o scope a ser aplicado:

def default_scope
:active
end

# Se params[:filters][:scope] = "pending"
scope # => "pending"

# Se não houver filtro
scope # => :active

search_param

Retorna o parâmetro de busca full-text:

# Request: /customers?filters[search]=João
search_param # => "João"

Métodos de Parents

get_parents

Retorna os objetos parent da URL aninhada:

# Request: /customers/123/pets/456
get_parents # => [#<Customer id: 123>]

set_parents

Configura os parents a partir dos parâmetros *_id:

# Chamado automaticamente
# Cria @customer a partir de customer_id
set_parents

Métodos de Parâmetros

parameters

Retorna todos os parâmetros como hash:

parameters
# => { controller: "...", action: "...", id: "...", customer: { name: "..." } }

object_parameters

Retorna os parâmetros permitidos do modelo:

# Request: { customer: { name: "João", email: "joao@email.com" } }
object_parameters
# => { name: "João", email: "joao@email.com" }

O método:

  • Aplica permit com os campos permitidos do modelo
  • Converte tipos especiais (money, date)

Métodos de Renderização

page_json

Gera o JSON completo da página:

def show
render json: page_json
end

Estrutura retornada:

{
request: { path: "/customers/123" },
resources: {
customer: { id: "123", name: "João", ... },
current_user: { id: "1", name: "Admin", ... },
filters: {},
params: {}
},
components: [
{ type: "fieldset", name: "customer_form", ... }
],
translations: {
"name" => { "name" => "Nome", "placeholder" => "..." }
},
options: {
layout: "default",
pagination: { customers: { per_page: 25, total_count: 100 } }
}
}

respond_to_api_with

Renderiza a resposta baseada na action:

def show
respond_to_api_with(object)
end

Métodos de Autorização

current_ability

Retorna a instância de Ability para o usuário atual:

current_ability  # => #<Ability:...>

authorization?

Verifica se autorização está habilitada:

if authorization?
objects.accessible_by(current_ability)
end

Callbacks

after_create

Executado após criar um registro:

def after_create
# Lógica pós-criação
end

after_update

Executado após atualizar um registro:

def after_update
# Lógica pós-atualização
end

after_destroy

Executado após excluir um registro:

def after_destroy
# Lógica pós-exclusão
end

Exemplo de Controller Customizado

class Api::V1::OrdersController < Nerdify::ApplicationController
authenticate User, auth_path: "users/sign_in"
template "nerdify/templates/application"

# Scope padrão
def default_scope
:pending
end

# Ordenação padrão
def default_order
:recent
end

# Adiciona recursos extras ao JSON
def page_json(action = nil)
json = super(action)

if params[:action] == "show"
json[:resources][:available_products] = Product.active.map(&:as_json)
end

json
end

# Action customizada
def approve
if object.can_approve?
object.update(status: "approved", approved_by: current_user)
render json: {
success: true,
toast: "Pedido aprovado!",
redirect_to: "/orders/#{object.id}"
}
else
render json: {
success: false,
errors: object.errors.full_messages
}, status: :unprocessable_entity
end
end

# Sobrescreve critérios
def criteria
base = super

# Adiciona filtro de loja do usuário
if current_user.store_id.present?
base[:store_id] = current_user.store_id
end

base
end
end

Boas Práticas

Faça

  • Use object e objects ao invés de queries diretas
  • Sobrescreva page_json para dados contextuais
  • Use default_scope para filtros padrão por perfil
  • Mantenha actions customizadas simples

Evite

  • Queries complexas dentro das actions
  • Ignorar accessible_by para autorização
  • Modificar object sem validação
  • Retornar dados sensíveis em page_json