Crecto API Reference
This reference captures the public APIs that exist in the repository today. All snippets are derived from the current code under src/crecto.
Crecto::Repo
Repositories are singletons that wrap a database connection.
Configuration
class Repo < Crecto::Repo
config do |conf|
conf.adapter = Crecto::Adapters::Postgres
conf.database = "app_dev"
conf.username = "postgres"
conf.password = "postgres"
conf.hostname = "localhost"
end
endconfig returns the same Config instance every time; use it to tweak settings at boot.
Reading
Repo.all(queryable, query = Crecto::Repo::Query.new, **opts)– returns anArray(queryable). Optional keywordpreload:merges extra preloads.Repo.get(queryable, id, tx = nil)/Repo.get!(...).Repo.get_by(queryable, **opts)/Repo.get_by!(...).Repo.get_association(model, :name, query = Query.new)– loads associations on demand.Repo.aggregate(queryable, function, field, query = Query.new)– executesAVG/COUNT/MAX/MIN/SUM.Repo.query(queryable, sql, params = [] of DbValue)– executes raw SQL, casting rows into models.Repo.query(sql, params = [] of DbValue)– returnsDB::ResultSet. Callers must close the result set.Repo.raw_exec(*args),Repo.raw_query(sql, *args),Repo.raw_scalar(*args)– thin wrappers around the underlyingDB::Database.
Writing
All mutating methods expect a valid changeset and return a Crecto::Changeset::Changeset.
Repo.insert(changeset)/Repo.insert!(changeset)Repo.update(changeset)/Repo.update!(changeset)Repo.delete(changeset)/Repo.delete!(changeset)Repo.insert_all(queryable, Array(Model | Hash | NamedTuple))– returnsCrecto::BulkResult. Hashes and named tuples are cast into models before validation.Repo.insert_all!(...)– raises if any record fails.Repo.update_all(queryable, query, Hash | NamedTuple, tx = nil)– returnsNil.Repo.delete_all(queryable, query = Query.new, tx = nil)– returnsNil.
Transactions
Repo.transaction(multi : Crecto::Multi)– runs the operations described by the multi and returns the same multi. If any operation fails the transaction is rolled back andmulti.errorscontains the failure details.Repo.transaction! { |tx| ... }– yields aCrecto::LiveTransaction. Any raised exception rolls back.Repo.transaction_with_savepoint!(name = nil) { |tx| ... }– creates a savepoint when already inside a transaction, otherwise behaves liketransaction!.
Crecto::LiveTransaction exposes the same methods as the repository (insert, update, delete, insert_all, update_all, delete_all, get, get_by). Each forwards to the repo while reusing the DB::Transaction.
Crecto::Repo::Query
The query builder composes SQL fragments.
Common helpers:
Query.where(...),Query.or_where(...)– accept keyword arguments,(String, Array(DbValue)),(Symbol, DbValue), or plain SQL.Query.join(:association)/Query.join("JOIN ...")Query.preload(:association, query = Query.new)Query.order_by("field DESC")Query.limit(Int32 | Int64)andQuery.offset(Int32 | Int64)Query.group_by("expression")Query.distinct("expression")Query.combine(other_query)– merges select lists and where expressions.Query.and { |expr| ... }andQuery.or { |expr| ... }– scope combinators.
Query#stream and Query#each_cursor exist as placeholders and currently raise NotImplementedError.
Crecto::Model
Subclassing Crecto::Model adds:
schemamacro for columns.- Association macros:
has_many,has_one,belongs_to.has_manyacceptsthrough:to model join tables. - Field introspection:
self.fields,self.primary_key_field,self.table_name. - Initializers:
new,new(**attrs)to apply attributes via the casting pipeline, andnew(named_tuple)for runtime data. - Changeset helpers:
self.changeset(instance, validation_context = nil),instance.get_changeset. - Casting helpers:
self.cast(hash),instance.cast(hash),cast!(...). - Timestamp helpers:
instance.created_at_to_now,instance.updated_at_to_now.
Associations store metadata in CRECTO_ASSOCIATIONS and raise Crecto::AssociationNotLoaded until preloaded.
Crecto::Changeset
Crecto::Changeset::Changeset instances expose:
#valid?– boolean result.#errors–Array(Tuple(String, String)).#changes/#source– change tracking.#instance– the wrapped model.#action– set by the repository (:insert,:update,:delete).#validate_required,#validate_format, etc. – imperative validators run inside custom logic.#unique_constraint(field)– converts database uniqueness violations into changeset errors.
Validations declared on the model class (e.g. validate_required) accumulate in class-level caches and run automatically when a changeset is instantiated.
Crecto::Multi
Crecto::Multi collects operations to run inside a transaction.
multi.insert(model_or_changeset)multi.update(model_or_changeset)multi.delete(model_or_changeset)multi.delete_all(queryable, query = Crecto::Repo::Query.new)multi.update_all(queryable, query, update_hash)multi.operations– the ordered list of pending operations.multi.errors– populated whenRepo.transaction(multi)encounters a failure.multi.changesets_valid?– returnsfalseand setserrorsif any queued changeset is invalid.
Crecto::BulkResult
Returned by Repo.insert_all.
#total_count,#successful_count,#failed_count#success_rate#inserted_ids#errors– array ofBulkInsertError#successful?,#partial_success?,#complete_failure?#finalize_result(duration_ms)– called internally to computefailed_count.
BulkInsertError provides index, error_message, error_class, validation_errors, database_error_code, and helpers like #constraint_violation?.
Errors
Defined under src/crecto/errors/:
Crecto::Errors::InvalidChangesetCrecto::Errors::InvalidAdapterCrecto::Errors::InvalidOptionCrecto::Errors::InvalidTypeCrecto::Errors::AssociationErrorCrecto::Errors::AssociationNotLoadedCrecto::Errors::BulkErrorCrecto::Errors::NoResultsCrecto::Errors::ConcurrentModificationErrorCrecto::Errors::RecordNotFoundErrorCrecto::Errors::IteratorError
Handle them with Crystal's standard exception mechanisms (rescue).
Logging
Crecto::DbLogger captures SQL statements, timings, and bulk operation diagnostics. Adapters call DbLogger.log and DbLogger.log_error internally. You can configure the logger by assigning Crecto::DbLogger.logger = Log.for("crecto").
This reference reflects the behaviour of the code as of the current repository revision. If you add new features, update this document alongside the implementation to keep it trustworthy.