Controllers
Trek::BaseController— the base for all admin controllers: authentication, authorization, localization, theadminlayout and Trek's form builder.Trek::ResourceController— extendsBaseControllerwith the full CRUD (index,show,new,create,edit,update,destroy), wired to ActionPolicy (authorized_scope,authorize!) and ordering. Scaffolded controllers inherit from it and only need to declare theirmodel:
module Admin
class BooksController < Trek::ResourceController
private
def model
Book
end
end
end- Panel controllers (
Trek::Panels::*) — support endpoints used by the admin UI: image uploads (Uppy), link insertion and content editor prompts.
Mixins
include Trek::Pagination— paginates the index with Kaminariinclude Trek::Search— filters the index byparams[:search]when the model is Searchableinclude Trek::Filters— filters the index by attribute equality (where(column => value)) fromparams[:filters]include Trek::Scopes— filters the index by named scopes fromparams[:scopes]
Filters
Trek::Filters lets users narrow an index by attribute values. Call apply_filters! in your index action — it rewrites @objects from params[:filters], applying a where(column => value) per non-blank filter (a value of "nil" matches NULL):
module Admin
class CitiesController < Trek::ResourceController
include Trek::Filters
helper_method :countries
def index
super
apply_filters!
end
private
def countries
City.distinct.pluck(:country_code).index_with { |code| I18n.t("countries.#{code}") }
end
end
endRender the choices with a ButtonGroupComponent, each button linking back to the index with the chosen filter:
= render Trek::ButtonGroupComponent.new do |g|
- g.with_button text: t("admin.actions.all"), \
href: [:admin, model], active: params.dig(:filters, :country_code).nil?
- countries.each do |code, name|
- g.with_button text: name, \
href: polymorphic_path([:admin, model], filters: { country_code: code }), \
active: code == params.dig(:filters, :country_code)If a controller includes
Trek::Filtersbut itsindexnever callsapply_filters!, anafter_actionraisesTrek::Filters::NotAppliedError(outside production) to flag the missing wiring.
Scopes
Trek::Scopes filters by named model scopes rather than raw attributes. Declare the allowed scopes via available_scopes, then call apply_scopes! in your index. It also exposes scope_counts and unscoped_objects helpers (the per-scope match counts and the pre-scope collection) for building scope tabs:
module Admin
class ArticlesController < Trek::ResourceController
include Trek::Scopes
def index
super
apply_scopes!
end
private
def available_scopes
%i[published draft]
end
end
endLike Trek::Filters, forgetting to call apply_scopes! raises Trek::Scopes::NotAppliedError outside production.