Skip to content

Instantly share code, notes, and snippets.

@dedemenezes
Created September 10, 2025 03:55
Show Gist options
  • Select an option

  • Save dedemenezes/8fec5aad902022de7e624b98fba02efa to your computer and use it in GitHub Desktop.

Select an option

Save dedemenezes/8fec5aad902022de7e624b98fba02efa to your computer and use it in GitHub Desktop.
class ProgramsController < ApplicationController
EDICAO_ATUAL = 12
# TODO: MAKE THIS ENV VARIABLE?
include BreadcrumbsHelper
DATES_PER_PAGE = 1
include Pagy::Backend
def index
items = [
# Links tem que vir do controller para incluir localizacao. Textos também
{ name: I18n.t("navigation.programming"), route: program_url, icon: "program" },
{ name: I18n.t("navigation.sessoes_com_convidados"), route: "/", icon: "user" },
{ name: I18n.t("navigation.mudancas_na_programacao"), route: "/", icon: "change" },
{ name: I18n.t("navigation.sessoes_ao_ar_livre"), route: "/", icon: "clock" }
]
selected_filters = {}
last_import_id = Programacao.maximum(:importacoesprog_id)
base_scope = Programacao
.joins(pelicula: :mostra)
.includes(:cinema, pelicula: :mostra)
.where(importacoesprog_id: last_import_id, edicao_id: EDICAO_ATUAL) # TODO: remover importacoes?
# Gathering filter options
paises_filter = base_scope.includes(pelicula: :paises)
.map { _1.pelicula.paises }
.flatten
.uniq
.sort_by { |it| it.nome_pais }
.as_json(only: %i[id nome_pais])
mostras_filter = Mostra.where(edicao_id: EDICAO_ATUAL)
.to_a
.uniq { |m| m.id }
.sort_by { |it| it.permalink_pt }
.as_json(
only: %i[id permalink_pt nome_abreviado],
methods: [ :tag_class, :display_name ]
)
cinemas_filter = Cinema.where(edicao_id: EDICAO_ATUAL).to_a.uniq { |m| m.id }.sort_by { |it| it.nome }.as_json(
only: %i[id nome endereco edicao_id]
)
# Log the SQL before the error
puts "=== BASE SCOPE SQL ==="
puts base_scope.to_sql
puts "====================="
# Filtering SEARCH INPUT
if params[:query].present?
term = "%#{params[:query].downcase}%"
# Use a subquery approach instead of raw SQL
pelicula_ids = Pelicula.where(
"LOWER(titulo_ingles_coord_int) LIKE :term OR
LOWER(titulo_original_coord_int) LIKE :term OR
LOWER(titulo_portugues_coord_int) LIKE :term OR
LOWER(titulo_ingles_semartigo) LIKE :term OR
LOWER(titulo_portugues_semartigo) LIKE :term",
term: term
).pluck(:id)
base_scope = base_scope.where(pelicula_id: pelicula_ids)
selected_filters[:query] = params[:query]
end
if params[:mostrasFilter].present?
selected_mostra = mostras_filter.find { |c| c["permalink_pt"] == params[:mostrasFilter] }
selected_filters[:mostrasFilter] = selected_mostra if selected_mostra
if selected_mostra
base_scope = base_scope.where(mostras: { permalink_pt: selected_filters[:mostrasFilter]["permalink_pt"] })
end
end
if params[:cinemasFilter]
selected_cinema = cinemas_filter.find do |cinema_filter|
(cinema_filter["id"].to_s === params[:cinemasFilter]) && (cinema_filter["edicao_id"] == EDICAO_ATUAL)
end
if selected_cinema
selected_filters[:cinemasFilter] = selected_cinema
base_scope = base_scope.where(cinema_id: selected_cinema["id"])
end
end
if params[:paisesFilter]
selected_pais = paises_filter.find do |pais_filter|
(pais_filter["id"].to_s === params[:paisesFilter])
end
if selected_pais
selected_filters[:paisesFilter] = selected_pais
# raise
# base_scope = base_scope.where(paises_id: selected_pais["id"])
base_scope = base_scope.joins(pelicula: :paises).where(pelicula: { paises: { id: selected_pais["id"] } })
end
end
# Get Scope Available dates
available_dates = base_scope.distinct.pluck(:data).sort
selected_date = available_dates.first
# Filter by date
if params[:date].present?
parsed_date = Date.parse(params[:date]) rescue nil
if parsed_date&.in?(available_dates)
selected_date = parsed_date
end
end
selected_filters[:date] = selected_date
programacoes_for_date = base_scope.where(data: selected_date).order(:sessao)
current_page = params[:page].to_i ||= 1
@pagy, @programacoes = pagy_infinite(programacoes_for_date, current_page)
@programacoes = @programacoes.map do |programacao|
{
id: programacao.id,
data: programacao.data,
sessao: [ programacao.display_sessao ],
cinema: programacao.cinema&.nome,
titulo: programacao.pelicula&.titulo_portugues_coord_int,
duracao: programacao.pelicula&.duracao_coord_int,
imagem: programacao.pelicula&.imagem,
genero: programacao.pelicula&.genre,
paises: programacao.pelicula&.display_paises,
mostra: programacao.pelicula&.mostra&.display_name,
mostra_tag_class: programacao.pelicula&.mostra&.tag_class
}
end
# display_selected_date = I18n.l(selected_date, format: "%a, %e %b", locale: :pt) if selected_date
@menu_tabs = available_dates.map do |date|
{
date: date,
url: build_tab_url(date, selected_filters),
active: date.to_s == params[:date] || (date == selected_date && !params[:date])
}
end
# Build breadcrumbs
# raise
render inertia: "ProgramPage", props: {
rootUrl: @root_url,
tabBaseUrl: program_url,
items:,
elements: @programacoes,
pagy: @pagy,
mostrasFilter: mostras_filter,
cinemasFilter: cinemas_filter,
paisesFilter: paises_filter,
menuTabs: @menu_tabs,
current_filters: {
query: params[:query],
mostrasFilter: selected_mostra,
cinemasFilter: selected_cinema,
paisesFilter: selected_pais
},
has_active_filters: params.permit(:query, :mostrasFilter).to_h.values.any?(&:present?),
crumbs: breadcrumbs(
[ "", @root_url ],
[ "Programação", "" ],
[ "Programação Completa", "" ],
)
}
end
private
# TODO: Relocate this piece into a concern or helper
def pagy_infinite(collection, page_param)
current_page = (page_param || params[:page] || 1).to_i
limit = Pagy::DEFAULT[:limit] || 5
if current_page <= 1
# First page - normal pagination
pagy_result = pagy(collection, limit: limit)
pagy_result
else
# Infinite scroll - load all items from page 1 to current page
total_items_needed = current_page * limit
# Get the actual items
items = collection.limit(total_items_needed)
# Create proper pagy object with
# all the metadata need in the frontend
total_count = collection.count
pagy_obj = Pagy.new(
count: total_count,
limit: limit,
page: current_page,
# overflow: :last_page
)
[ pagy_obj, items ]
end
end
def build_tab_url(date, filters)
query_params = {}
query_params[:mostrasFilter]= filters[:mostrasFilter]["permalink_pt"] if filters[:mostrasFilter].present?
query_params[:cinemasFilter]= filters[:cinemasFilter]["id"] if filters[:cinemasFilter].present?
query_params[:paisesFilter]= filters[:paisesFilter]["id"] if filters[:paisesFilter].present?
query_params[:date] = date
url_for(params: query_params, only_path: true)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment