def ultimo_boleto
boletos.order('id desc').first # o order faz com que rode muitos selects
# ou
boletos.first # ou .last - me faz confiar cegamente na ordenação da querie complexa (qualquer erro é fatal)
end
def ultimo_boleto_ocorrencia
ultimo_boleto.order('id desc').last # idem
ultimo_boleto.boleto_ocorrencias.last # idem
end
- Contras
-
- querie de dificil manutenção e qualquer erro é fatal
-
- se o dev mexer no na coleção de boletos, a performance pode ser perdida
- Prós:
-
- Não precisa guardar campos a mais na tabela de cobranças e boletos
:cobranca belongs_to :ultimo_boleto
:boleto belongs_to :ultimo_boleto_ocorrencia
cobranca.ultimo_boleto
boleto.ultimo_boleto_ocorrencia
- Prós:
-
- Fácil conseguir performance com este comando Cobranca.includes(ultimo_boleto: ultimo_boleto_ocorrencia)
-
- Baixa chance do ultimo boleto não ser o ultimo
- Contras
-
- Um campo a mais em cobranca (ultimo_boleto_id)
-
- Um campo a mais em boleto (ultimo_boleto_ocorrencia_id)
A
SELECT *
FROM
"financeiro_cobrancas"
LEFT OUTER JOIN
-- aqui ficaria o left outer join com unidade
LEFT OUTER JOIN
-- aqui ficaria o left outer join com pagador
LEFT OUTER JOIN
"financeiro_boletos" ON financeiro_boletos.id =
(SELECT
MAX(financeiro_boletos.id)
FROM
financeiro_boletos
WHERE
financeiro_boletos.cobranca_id = financeiro_cobrancas.id)
AND
"financeiro_boletos"."cobranca_id" = "financeiro_cobrancas"."id"
-- LEFT OUTER JOIN
LEFT OUTER JOIN
"financeiro_boleto_ocorrencias" ON financeiro_boleto_ocorrencias.id =
(
SELECT
MAX(financeiro_boleto_ocorrencias.id)
FROM
financeiro_boleto_ocorrencias
WHERE
financeiro_boleto_ocorrencias.boleto_id = financeiro_boletos.id
)
AND
"financeiro_boleto_ocorrencias"."cobranca_id" = "financeiro_cobrancas"."id"
AND
"financeiro_boleto_ocorrencias"."remessa_id" IS NULL
AND
"financeiro_boleto_ocorrencias"."cancelada_em" IS NULL
AND
"financeiro_boleto_ocorrencias"."boleto_id" = "financeiro_boletos"."id"
WHERE
--
--Aqui vem a busca do filtro avançado ou simples
--
-- se comentar estas duas linhas abaixo conseguimos cobranças sem boletos (left outer join)
AND
"financeiro_boletos"."id" IS NOT NULL
AND
"financeiro_boleto_ocorrencias"."id" IS NOT NULL
;