### Clone and Run Minimal Example Source: https://github.com/vincit/objection.js/blob/main/doc/guide/getting-started.md Clones the objection.js repository, navigates to the minimal example directory, installs dependencies, and starts the application. This demonstrates the basic setup for testing objection.js. ```bash git clone git@github.com:Vincit/objection.js.git objection cd objection/examples/minimal npm install npm start ``` -------------------------------- ### Install and Run Koa Example Source: https://github.com/vincit/objection.js/blob/main/examples/koa/README.md Commands to clone the project repository, navigate to the Koa example directory, install Node.js dependencies, start the Koa server, and run the client script. ```sh git clone git@github.com:Vincit/objection.js.git objection cd objection/examples/koa npm install npm start node client.js ``` -------------------------------- ### Clone and Run Koa Example Source: https://github.com/vincit/objection.js/blob/main/doc/guide/getting-started.md Clones the objection.js repository, navigates to the koa example directory, installs dependencies, and starts the Koa server. This project includes HTTP requests for interacting with a REST API. ```bash git clone git@github.com:Vincit/objection.js.git objection cd objection/examples/koa npm install npm start ``` -------------------------------- ### Install and Run Objection.js Minimal Example Source: https://github.com/vincit/objection.js/blob/main/examples/minimal/README.md This snippet provides the shell commands required to clone the Objection.js repository, navigate to the minimal example directory, install dependencies using npm, and start the application. ```sh git clone git@github.com:Vincit/objection.js.git objection cd objection/examples/minimal npm install npm start ``` -------------------------------- ### Install and Run Koa TypeScript Example Source: https://github.com/vincit/objection.js/blob/main/examples/koa-ts/README.md Provides the necessary shell commands to clone the objection.js repository, navigate to the Koa TypeScript example directory, install project dependencies using npm, and start the server and client applications. ```bash git clone git@github.com:Vincit/objection.js.git objection cd objection/examples/koa-ts npm install npm start node client.js ``` -------------------------------- ### Standalone Objection.js Example Source: https://github.com/vincit/objection.js/blob/main/doc/guide/getting-started.md A self-contained JavaScript example demonstrating how to initialize Objection.js with Knex, define a model with relations, create a schema, and perform basic database operations like inserting and fetching data. ```javascript // run the following command to install: // npm install objection knex sqlite3 const { Model } = require('objection'); const Knex = require('knex'); // Initialize knex. const knex = Knex({ client: 'sqlite3', useNullAsDefault: true, connection: { filename: 'example.db' } }); // Give the knex instance to objection. Model.knex(knex); // Person model. class Person extends Model { static get tableName() { return 'persons'; } static get relationMappings() { return { children: { relation: Model.HasManyRelation, modelClass: Person, join: { from: 'persons.id', to: 'persons.parentId' } } }; } } async function createSchema() { if (await knex.schema.hasTable('persons')) { return; } // Create database schema. You should use knex migration files // to do this. We create it here for simplicity. await knex.schema.createTable('persons', table => { table.increments('id').primary(); table.integer('parentId').references('persons.id'); table.string('firstName'); }); } async function main() { // Create some people. const sylvester = await Person.query().insertGraph({ firstName: 'Sylvester', children: [ { firstName: 'Sage' }, { firstName: 'Sophia' } ] }); console.log('created:', sylvester); // Fetch all people named Sylvester and sort them by id. // Load `children` relation eagerly. const sylvesters = await Person.query() .where('firstName', 'Sylvester') .withGraphFetched('children') .orderBy('id'); console.log('sylvesters:', sylvesters); } createSchema() .then(() => main()) .then(() => knex.destroy()) .catch(err => { console.error(err); return knex.destroy(); }); ``` -------------------------------- ### Start Documentation Development Server Source: https://github.com/vincit/objection.js/blob/main/doc/guide/contributing.md Starts a local development server for the documentation site. Changes to markdown files in the 'doc' folder will be reflected here. ```bash npm run docs:dev ``` -------------------------------- ### Install Latest Development Version Source: https://github.com/vincit/objection.js/blob/main/doc/guide/README.md Installs the latest alpha, beta, or release candidate version of Objection.js using the '@next' tag. ```bash npm install objection@next ``` -------------------------------- ### Install Latest Development Version Source: https://github.com/vincit/objection.js/blob/main/doc/guide/installation.md Installs the latest alpha, beta, or release candidate version of Objection.js using the '@next' tag. ```bash npm install objection@next ``` -------------------------------- ### Install Objection and Knex Source: https://github.com/vincit/objection.js/blob/main/doc/guide/README.md Installs the Objection.js ORM and its required database access layer, Knex.js. Use npm or yarn for installation. ```bash npm install objection knex yarn add objection knex ``` -------------------------------- ### Install Database Drivers Source: https://github.com/vincit/objection.js/blob/main/doc/guide/installation.md Installs specific database drivers required by Knex.js to connect to your chosen database. Examples include PostgreSQL (pg), SQLite3, MySQL, and MySQL2. ```bash npm install pg npm install sqlite3 npm install mysql npm install mysql2 ``` -------------------------------- ### Install Database Drivers Source: https://github.com/vincit/objection.js/blob/main/doc/guide/README.md Installs specific database drivers required by Knex.js to connect to your chosen database. Examples include PostgreSQL (pg), SQLite3, MySQL, and MySQL2. ```bash npm install pg npm install sqlite3 npm install mysql npm install mysql2 ``` -------------------------------- ### Install Objection and Knex Source: https://github.com/vincit/objection.js/blob/main/doc/guide/installation.md Installs the Objection.js ORM and its required database access layer, Knex.js. Use npm or yarn for installation. ```bash npm install objection knex yarn add objection knex ``` -------------------------------- ### Setup Test Databases Source: https://github.com/vincit/objection.js/blob/main/doc/guide/contributing.md Executes a script to create test users and databases, essential for running the project's test suite. ```bash node setup-test-db ``` -------------------------------- ### Install Project Dependencies Source: https://github.com/vincit/objection.js/blob/main/doc/guide/contributing.md Command to install all necessary dependencies for the Objection.js project using npm. This should be run after cloning the repository. ```bash npm install ``` -------------------------------- ### Start Docker Compose Services Source: https://github.com/vincit/objection.js/blob/main/doc/guide/contributing.md Command to start the required services using Docker Compose. Ensure no local databases are running on conflicting ports before execution. ```bash docker compose up ``` -------------------------------- ### Run Tests on Specific Databases Source: https://github.com/vincit/objection.js/blob/main/doc/guide/contributing.md Example of running tests against a specific database, like SQLite, without needing Docker Compose. ```bash DATABASES=sqlite3 npm test ``` -------------------------------- ### Clone Objection.js Repository Source: https://github.com/vincit/objection.js/blob/main/doc/guide/contributing.md Instructions to clone the Objection.js project repository from GitHub. This is the first step in setting up the development environment. ```bash git clone git@github.com:/objection.js.git objection ``` -------------------------------- ### Complete Migration Example with JSONB Indexes Source: https://github.com/vincit/objection.js/blob/main/doc/recipes/indexing-postgresql-jsonb-columns.md A full Objection.js migration example demonstrating the creation of tables ('Hero', 'Place') with JSONB columns and applying different types of indexes (full GIN, partial GIN with path_ops, and expression index). ```js exports.up = knex => { return knex.schema .createTable('Hero', table => { table.increments('id').primary(); table.string('name'); table.jsonb('details'); table .integer('homeId') .unsigned() .references('id') .inTable('Place'); }) .raw('CREATE INDEX on ?? USING GIN (??)', ['Hero', 'details']) .raw("CREATE INDEX on ?? ((??#>>'{type}'))", ['Hero', 'details']) .createTable('Place', table => { table.increments('id').primary(); table.string('name'); table.jsonb('details'); }) .raw('CREATE INDEX on ?? USING GIN (?? jsonb_path_ops)', [ 'Place', 'details' ]); }; ``` -------------------------------- ### Objection.js Knex Config for Older Nodes Source: https://github.com/vincit/objection.js/blob/main/doc/api/objection/README.md Provides an example of configuring Knex.js with Objection.js's `knexIdentifierMapping` utility, suitable for environments or Node.js versions that might require a slightly different import or setup pattern. ```js const Knex = require('knex'); const knexIdentifierMapping = require('objection').knexIdentifierMapping; const knex = Knex({ client: 'postgres', connection: { host: '127.0.0.1', user: 'objection', database: 'objection_test' }, ...knexIdentifierMapping({ MyId: 'id', MyProp: 'prop', MyAnotherProp: 'anotherProp' }) }); ``` -------------------------------- ### Relation Expression Syntax and Examples Source: https://github.com/vincit/objection.js/blob/main/doc/guide/query-examples.md Defines the syntax for specifying relations to be fetched eagerly. Expressions are typically strings, but an object notation is also supported. Examples illustrate valid and invalid patterns. ```APIDOC Relation Expressions: - Strings or objects defining graph structures. - Can be chained using dots (e.g., 'children.pets'). - Can be combined using commas within brackets (e.g., '[pets, children]'). Allowed Examples: - 'pets' - 'children' - 'children.pets' - '[pets, children]' - '[pets, children.pets]' Disallowed Examples (if not explicitly allowed): - 'movies' - 'children.children' - '[pets, children.children]' - 'notEvenAnExistingRelation' ``` -------------------------------- ### Run Project Tests Source: https://github.com/vincit/objection.js/blob/main/doc/guide/contributing.md Command to execute the full test suite for Objection.js. This verifies the project's integrity and your changes. ```bash npm test ``` -------------------------------- ### Objection.js: Update and Patch Data Source: https://github.com/vincit/objection.js/blob/main/doc/guide/query-examples.md Illustrates updating and patching records by ID or with conditions using Objection.js. Shows how to get the number of updated rows or fetch the updated item. ```JavaScript const numUpdated = await Person.query() .findById(1) .patch({ firstName: 'Jennifer' }); ``` ```SQL update "persons" set "firstName" = 'Jennifer' where "id" = 1 ``` ```JavaScript const numUpdated = await Person.query() .patch({ lastName: 'Dinosaur' }) .where('age', '>', 60); console.log('all people over 60 years old are now dinosaurs'); console.log(numUpdated, 'people were updated'); ``` ```SQL update "persons" set "lastName" = 'Dinosaur' where "age" > 60 ``` ```JavaScript const updatedPerson = await Person.query().patchAndFetchById(246, { lastName: 'Updated' }); console.log(updatedPerson.lastName); // --> Updated. ``` ```SQL update "persons" set "lastName" = 'Updated' where "id" = 246 select "persons".* from "persons" where "id" = 246 ``` -------------------------------- ### HasOneRelation Example Source: https://github.com/vincit/objection.js/blob/main/doc/guide/relations.md Shows the setup for a `HasOneRelation` in Objection.js. This is similar to `HasManyRelation` but is used when a source model is related to only one instance of the related model. ```javascript class Person extends Model { static tableName = 'persons'; static relationMappings = { animal: { relation: Model.HasOneRelation, modelClass: Animal, join: { from: 'persons.id', to: 'animals.ownerId' } } }; } ``` -------------------------------- ### Objection.js Module Import Source: https://github.com/vincit/objection.js/blob/main/doc/api/objection/README.md Demonstrates how to import the main objection module and essential components like Model and ref. This is the standard starting point for using Objection.js. ```js const objection = require('objection'); const { Model, ref } = require('objection'); ``` -------------------------------- ### Objection.js Initialize Function Source: https://github.com/vincit/objection.js/blob/main/doc/api/objection/README.md Explains and demonstrates the use of the `initialize` function, which performs asynchronous preparations like fetching table metadata. It's optional but useful for synchronous query building or controlling preparation execution timing, especially in tests. ```js const { initialize } = require('objection'); // Example usage with knex and models await initialize(knex, [Person, Movie, Pet, SomeOtherModelClass]); // Example usage omitting knex if globally configured await initialize([Person, Movie, Pet, SomeOtherModelClass]); ``` -------------------------------- ### Relating Specific Paths with `relate: ['path']` Source: https://github.com/vincit/objection.js/blob/main/doc/guide/query-examples.md Explains how to use `relate` with an array of relation paths (e.g., `['children', 'children.movies.actors']`) to control which parts of the graph get related, even if they have identifiers. This offers granular control over relationships. ```js await Person.query().insertGraph( [ { firstName: 'Jennifer', lastName: 'Lawrence', movies: [ { id: 2636 } ] } ], { relate: ['movies'] } ); ``` ```js await Person.query().insertGraph( [ { firstName: 'Jennifer', lastName: 'Lawrence', movies: [ { name: 'Silver Linings Playbook', duration: 122, actors: [ { id: 2516 } ] } ] } ], { relate: ['movies.actors'] } ); ``` -------------------------------- ### Objection.js Example Database Structure Source: https://github.com/vincit/objection.js/blob/main/doc/guide/query-examples.md An example of a complex data structure with nested relations (BelongsToOne, HasMany, ManyToMany) used to illustrate Objection.js upsertGraph functionality. ```js [ { id: 1, firstName: 'Jennifer', lastName: 'Aniston', // This is a BelongsToOneRelation parent: { id: 2, firstName: 'Nancy', lastName: 'Dow' }, // This is a HasManyRelation pets: [{ id: 1, name: 'Doggo', species: 'Dog', }, { id: 2, name: 'Kat', species: 'Cat', }], // This is a ManyToManyRelation movies: [{ id: 1, name: 'Horrible Bosses', reviews: [{ id: 1, title: 'Meh', stars: 3, text: 'Meh' }] }, { id: 2, name: 'Wanderlust', reviews: [{ id: 2, title: 'Brilliant', stars: 5, text: 'Makes me want to travel' }] }] }] ``` -------------------------------- ### Add a Pet using Static RelatedQuery Source: https://github.com/vincit/objection.js/blob/main/doc/guide/query-examples.md Shows an alternative way to add a pet to a person using the static `relatedQuery` method, which is often considered a cleaner approach in Objection.js. Includes the corresponding SQL. ```js const fluffy = await Person.relatedQuery('pets') .for(1) .insert({ name: 'Fluffy' }); ``` ```sql insert into "animals" ("name", "ownerId") values ('Fluffy', 1) ``` -------------------------------- ### ManyToManyRelation Example Source: https://github.com/vincit/objection.js/blob/main/doc/guide/relations.md Provides an example of `ManyToManyRelation` configuration in Objection.js. This is used when models are related through an intermediate join table, allowing many-to-many associations. ```javascript class Person extends Model { static tableName = 'persons'; static relationMappings = { movies: { relation: Model.ManyToManyRelation, modelClass: Movie, join: { from: 'persons.id', through: { // persons_movies is the join table. from: 'persons_movies.personId', to: 'persons_movies.movieId' }, to: 'movies.id' } } }; } ``` -------------------------------- ### Objection.js Instance Methods Source: https://github.com/vincit/objection.js/blob/main/doc/api/model/instance-methods.md Documentation for common instance methods on Objection.js models, including data setting, relation management, and fetching. ```APIDOC $setDatabaseJson(json) Sets the values from a JSON object in database format. - Parameters: - json: Object - The JSON POJO in database format. - Returns: - [Model]: `this` for chaining. ``` ```APIDOC $set(obj) Sets the values from another model instance or object. Unlike $setJson, this doesn't call any $parseJson hooks or validate the input. This simply sets each value in the object to this object. - Parameters: - obj: Object - The values to set. - Returns: - [Model]: `this` for chaining. ``` ```APIDOC $setRelated(relation, relatedModels) Sets related models to a corresponding property in the object. - Parameters: - relation: string | [Relation](/api/types/#class-relation) - Relation name or a relation instance to set. - relatedModels: [Model](/api/model/) | [Model][]\[] - Models to set. - Returns: - [Model]: `this` for chaining. - Examples: - person.$setRelated('parent', parent); - person.$setRelated('children', children); ``` ```APIDOC $appendRelated(relation, relatedModels) Appends related models to a corresponding property in the object. - Parameters: - relation: string | [Relation](/api/types/#class-relation) - Relation name or a relation instance to append to. - relatedModels: [Model](/api/model/) | [Model][]\[] - Models to append. - Returns: - [Model]: `this` for chaining. - Examples: - person.$appendRelated('parent', parent); - person.$appendRelated('children', child1); - person.$appendRelated('children', child2); ``` ```APIDOC $fetchGraph(expression, options) Shortcut for [Person.fetchGraph(person, options)](/api/model/static-methods.html#static-fetchgraph). - Parameters: - expression: Any - The graph fetch expression. - options: Object - Fetch options. ``` ```APIDOC $traverse(filterConstructor, callback) Shortcut for [Model.traverse(filterConstructor, this, callback)](/api/model/static-methods.html#static-traverse). - Parameters: - filterConstructor: Function - Constructor to filter by. - callback: Function - Callback function to execute. ``` ```APIDOC $traverseAsync(filterConstructor, callback) Shortcut for [Model.traverseAsync(filterConstructor, this, callback)](/api/model/static-methods.html#static-traverseasync). - Parameters: - filterConstructor: Function - Constructor to filter by. - callback: Function - Async callback function to execute. ``` ```APIDOC $knex() Shortcut for [Person.knex()](/api/model/static-methods.html#static-knex). - Returns: - Knex: The underlying Knex instance. ``` ```APIDOC $transaction() Shortcut for [Person.knex()](/api/model/static-methods.html#static-knex). - Returns: - KnexTransaction: The underlying Knex transaction instance. ``` -------------------------------- ### Query with Relation Join Source: https://github.com/vincit/objection.js/blob/main/doc/guide/query-examples.md Demonstrates joining related models using the `joinRelated` method. This example selects the grandparent's name by joining through the 'parent' relation twice. ```javascript const people = await Person.query() .select('parent:parent.name as grandParentName') .joinRelated('parent.parent'); console.log(people[0].grandParentName); ``` ```sql select "parent:parent"."firstName" as "grandParentName" from "persons" inner join "persons" as "parent" on "parent"."id" = "persons"."parentId" inner join "persons" as "parent:parent" on "parent:parent"."id" = "parent"."parentId" ``` -------------------------------- ### Model Instance Methods Source: https://github.com/vincit/objection.js/blob/main/doc/api/model/instance-methods.md Comprehensive documentation for core model instance methods in objection.js, including cloning, JSON serialization for various contexts, and database data transformation. ```APIDOC $clone(options) - Returns a (deep) copy of a model instance. - If the item to be cloned has instances of [Model](/api/model/) as properties (or arrays of them), they are cloned using their `$clone()` method. - A shallow copy without relations can be created by passing the `shallow: true` option. - Arguments: - opt: [CloneOptions](/api/types/#type-cloneoptions) - Optional options. - Returns: - [Model](/api/model/) - Deep clone of `this`. - Examples: - const shallowClone = modelInstance.$clone({ shallow: true }); toJSON(opt) - Exports this model as a JSON object. - See [this section](/api/model/overview.html#model-data-lifecycle) for more information. - Arguments: - opt: [ToJsonOptions](/api/types/#type-tojsonoptions) - Optional options. - Returns: - Object - Model as a JSON object. - Examples: - const shallowObj = modelInstance.toJSON({ shallow: true, virtuals: false }); - const onlySomeVirtuals = modelInstance.toJSON({ virtuals: ['fullName'] }); $toJson() - Alias for [toJSON](/api/model/instance-methods.html#tojson). $toDatabaseJson() - Exports this model as a database JSON object. - This method is called internally to convert a model into a database row. - See [this section](/api/model/overview.html#model-data-lifecycle) for more information. - Returns: - Object - Database row. $parseDatabaseJson(json) - This is called when a [Model](/api/model/) instance is created from a database JSON object. - This method converts the JSON object from the database format to the internal format. - You can override this method to carry out whatever conversions you want for the data when it's fetched from the database, before it's converted into a model instance. - See [this section](/api/model/overview.html#model-data-lifecycle) for more information. - Requirements: 1. This function must be pure. It shouldn't have any side effects because it is called from "unexpected" places (for example to determine if your model somehow transforms column names between db and code). 2. This function must be able to handle any subset of the model's properties coming in. You cannot assume that some column is present in the `json` object as it depends on the select statement. There can also be additional columns because of joins, aliases etc. This method must also be prepared for null values in _any_ property of the `json` object. - Arguments: - json: Object - The JSON POJO in database format. - Returns: - Object - The JSON POJO in internal format. - Example: - class Person extends Model { $parseDatabaseJson(json) { // Remember to call the super class's implementation. json = super.$parseDatabaseJson(json); // Do your conversion here. return json; } } ``` -------------------------------- ### `withGraphJoined` vs `withGraphFetched` Source: https://github.com/vincit/objection.js/blob/main/doc/guide/query-examples.md Compares `withGraphJoined` with `withGraphFetched`, highlighting that `withGraphJoined` allows referring to related items from the root query because they are all joined. Includes examples of filtering on joined tables. ```javascript const people = await Person.query() .withGraphJoined('[pets, children.pets]') .where('pets.age', '>', 10) .where('children:pets.age', '>', 10); ``` -------------------------------- ### Objection.js: Mutate Methods API Reference Source: https://github.com/vincit/objection.js/blob/main/doc/guide/query-examples.md API documentation for Objection.js mutate methods, including insert, insertGraph, update, patch, delete, and related fetch methods. Details on return values and differences between update/patch. ```APIDOC insert(modelOrObject: Model | Model[] | object | object[]): QueryBuilder - Inserts one or more models or plain objects into the database. - Parameters: - modelOrObject: A single model instance, an array of model instances, a plain object, or an array of plain objects to insert. - Returns: The inserted model instance(s) or plain object(s) with IDs populated. insertGraph(modelOrObject: Model | Model[] | object | object[]): QueryBuilder - Inserts a graph of models or plain objects, handling relations. - See: [graph inserts](/guide/query-examples.html#graph-inserts) update(modelOrObject: object): QueryBuilder - Updates existing rows in the database. - Parameters: - modelOrObject: An object containing the fields to update. - Returns: The number of updated rows. patch(modelOrObject: object): QueryBuilder - Patches existing rows in the database with provided values. - Differences from `update`: `patch` is generally for partial updates and may have different default behaviors or optimizations. - Parameters: - modelOrObject: An object containing the fields to patch. - Returns: The number of updated rows. updateAndFetchById(id: IdType, modelOrObject: object): QueryBuilder - Updates a single row by its ID and fetches the updated model. - Parameters: - id: The ID of the row to update. - modelOrObject: An object containing the fields to update. - Returns: The updated model instance. patchAndFetchById(id: IdType, modelOrObject: object): QueryBuilder - Patches a single row by its ID and fetches the updated model. - Parameters: - id: The ID of the row to patch. - modelOrObject: An object containing the fields to patch. - Returns: The updated model instance. delete(): QueryBuilder - Deletes rows from the database based on the query's WHERE clauses. - Returns: The number of deleted rows. deleteById(id: IdType): QueryBuilder - Deletes a single row by its ID. - Parameters: - id: The ID of the row to delete. - Returns: The number of deleted rows. returning(columns: string | string[]): QueryBuilder - Specifies columns to return after an insert, update, or delete operation (e.g., on PostgreSQL). - Example: `.returning('*')` to return all columns. - See: [returning tricks recipe](/recipes/returning-tricks.html) ``` -------------------------------- ### Objection.js Model bindKnex Example Source: https://github.com/vincit/objection.js/blob/main/doc/api/model/static-methods.md Demonstrates how to bind different Knex.js instances to an Objection.js model, allowing for distinct database connections per model instance. It shows creating bound models and executing queries. ```javascript const knex1 = require('knex')({ client: 'sqlite3', connection: { filename: 'database1.db' } }); const knex2 = require('knex')({ client: 'sqlite3', connection: { filename: 'database2.db' } }); // Throws since the knex instance is null. // await SomeModel.query(); const BoundModel1 = SomeModel.bindKnex(knex1); const BoundModel2 = SomeModel.bindKnex(knex2); // Works. const models1 = await BoundModel1.query(); console.log(models1[0] instanceof SomeModel); // --> true console.log(models1[0] instanceof BoundModel1); // --> true // Works. const models2 = await BoundModel2.query(); console.log(models2[0] instanceof SomeModel); // --> true console.log(models2[0] instanceof BoundModel2); // --> true ``` -------------------------------- ### Delete Multiple Items by Condition Source: https://github.com/vincit/objection.js/blob/main/doc/guide/query-examples.md Shows how to delete multiple records that match specific criteria. This example uses the `delete` and `where` methods, allowing for complex filtering conditions, including case-insensitive comparisons. ```js const numDeleted = await Person.query() .delete() .where(raw('lower("firstName")'), 'like', '%ennif%'); console.log(numDeleted, 'people were deleted'); ``` ```sql delete from "persons" where lower("firstName") like '%ennif%' ``` -------------------------------- ### Start Transaction with Explicit Knex Instance Source: https://github.com/vincit/objection.js/blob/main/doc/guide/transactions.md Starts a database transaction using Objection.js's `Model.transaction` method, explicitly passing a Knex instance. This is useful when a global Knex instance is not set via `Model.knex()`. ```js await Person.transaction(knex, async trx => { ... }); ``` -------------------------------- ### $afterFind Method Example Source: https://github.com/vincit/objection.js/blob/main/doc/api/model/instance-methods.md Demonstrates using queryContext.transaction within the $afterFind lifecycle hook. This ensures that queries executed within this hook are run within the original query's transaction context, even if no explicit transaction is active. ```javascript class Person extends Model { $afterFind(queryContext) { // This can always be done even if there is no running transaction. // In that case `queryContext.transaction` returns the normal knex // instance. This makes sure that the query is not executed outside // the original query's transaction. return SomeModel.query(queryContext.transaction).insert(whatever); } } ``` -------------------------------- ### Example Usage for `allowGraph` in Express Source: https://github.com/vincit/objection.js/blob/main/doc/guide/query-examples.md Shows how to integrate `allowGraph` into an Express route handler. This method validates and fetches graphs specified by user input (e.g., query parameters), preventing unauthorized eager loading. ```javascript expressApp.get('/people', async (req, res) => { const people = await Person.query() .allowGraph('[pets, children.pets]') .withGraphFetched(req.query.eager); res.send(people); }); ``` -------------------------------- ### Objection.js: Insert Data Source: https://github.com/vincit/objection.js/blob/main/doc/guide/query-examples.md Demonstrates inserting single records and records with subqueries using Objection.js's `insert` method. Includes corresponding SQL statements for clarity. ```JavaScript const jennifer = await Person.query().insert({ firstName: 'Jennifer', lastName: 'Lawrence' }); console.log(jennifer instanceof Person); // --> true console.log(jennifer.firstName); // --> 'Jennifer' console.log(jennifer.fullName()); // --> 'Jennifer Lawrence' ``` ```SQL insert into "persons" ("firstName", "lastName") values ('Jennifer', 'Lawrence') ``` ```JavaScript const jennifer = await Person.query().insert({ firstName: 'Average', lastName: 'Person', age: Person.query().avg('age') }); ``` -------------------------------- ### Relate Multiple Movies to a Person Source: https://github.com/vincit/objection.js/blob/main/doc/guide/query-examples.md Illustrates relating multiple existing movies to a person, including a subquery to find the target person by name. This example notes potential database-specific behavior. Includes the corresponding SQL. ```js await Person.relatedQuery('movies') .for( Person.query() .where('firstName', 'Arnold') .limit(1) ) .relate([100, 200, 300, 400]); ``` ```sql insert into "persons_movies" ("personId", "movieId") values (/* Arnold's ID */, 100) insert into "persons_movies" ("personId", "movieId") values (/* Arnold's ID */, 200) insert into "persons_movies" ("personId", "movieId") values (/* Arnold's ID */, 300) insert into "persons_movies" ("personId", "movieId") values (/* Arnold's ID */, 400) ``` -------------------------------- ### Query with Grouping and OR Condition Source: https://github.com/vincit/objection.js/blob/main/doc/guide/query-examples.md Shows how to use a builder callback for complex WHERE clauses, including OR conditions, and demonstrates the use of arrow functions for cleaner syntax in Objection.js compared to raw Knex. ```javascript const nonMiddleAgedJennifers = await Person.query() .where(builder => builder.where('age', '<', 40).orWhere('age', '>', 60)) .where('firstName', 'Jennifer') .orderBy('lastName'); console.log('The last name of the first non middle aged Jennifer is'); console.log(nonMiddleAgedJennifers[0].lastName); ``` ```sql select "persons".* from "persons" where ("age" < 40 or "age" > 60) and "firstName" = 'Jennifer' order by "lastName" asc ``` -------------------------------- ### Fetch Person and their Pets (Two Queries) Source: https://github.com/vincit/objection.js/blob/main/doc/guide/query-examples.md Fetches a person by ID and then queries for their related pets, filtering by species and ordering by name. This approach requires two separate database queries. ```js const person = await Person.query().findById(1); const dogs = await person .$relatedQuery('pets') .where('species', 'dog') .orderBy('name'); ``` ```sql select "persons".* from "persons" where "persons"."id" = 1 select "animals".* from "animals" where "species" = 'dog' and "animals"."ownerId" = 1 order by "name" asc ``` -------------------------------- ### Start Manual Transaction with Model.startTransaction Source: https://github.com/vincit/objection.js/blob/main/doc/guide/transactions.md Starts a database transaction using Objection.js's `Model.startTransaction` method. This method returns a transaction object that must be manually committed or rolled back. It provides more granular control over the transaction lifecycle. ```js const { transaction } = require('objection'); const trx = await Person.startTransaction(); try { // Use the transaction object 'trx' for queries await trx.commit(); } catch (err) { await trx.rollback(); throw err; } ``` -------------------------------- ### Objection.js Model Instance Methods API Source: https://github.com/vincit/objection.js/blob/main/doc/api/model/instance-methods.md API documentation for Objection.js model instance methods, detailing their signatures, parameters, return values, and potential exceptions. ```APIDOC $id(id) Returns or sets the identifier of a model instance. - id: The identifier to set (optional). - Returns: The model's ID if no argument is provided, or the model instance for chaining if an ID is set. $beforeValidate(jsonSchema, json, opt) Hook called before validation. - jsonSchema: A deep clone of this class's jsonSchema. - json: The JSON object to be validated. - opt: Optional options, including `opt.old` for existing values. - Returns: The modified jsonSchema or the input jsonSchema. $afterValidate(json, opt) Hook called after successful validation. - json: The JSON object to be validated. - opt: Optional options, including `opt.old` for existing values. $validate() Validates the model instance by calling $beforeValidate and $afterValidate. - Throws: ValidationError if validation fails. $omitFromJson(props) Omits a set of properties when converting the model to JSON. - props: string | string[] | Object - Properties to omit. - Returns: `this` for chaining. $omitFromDatabaseJson(props) Omits a set of properties when converting the model to database JSON. - props: string | string[] | Object - Properties to omit. - Returns: `this` for chaining. ``` -------------------------------- ### Limit Recursive Relation Fetching Depth Source: https://github.com/vincit/objection.js/blob/main/doc/guide/query-examples.md Shows how to limit the depth of recursive relation fetching using `.^N` notation, preventing infinite loops or excessive data fetching. This example limits recursion to 3 levels. ```javascript const people = await Person.query().withGraphFetched('[pets, children.^3]'); console.log(people[0].children[0].children[0].children[0].firstName); ``` -------------------------------- ### Fetch Pets for Multiple People Source: https://github.com/vincit/objection.js/blob/main/doc/guide/query-examples.md Fetches pets for multiple people identified by an array of IDs in a single query. The `for` method accepts an array to query across multiple owners efficiently. ```js const dogs = await Person.relatedQuery('pets') .for([1, 2]) .where('species', 'dog') .orderBy('name'); ``` ```sql select "animals".* from "animals" where "species" = 'dog' and "animals"."ownerId" in (1, 2) order by "name" asc ``` -------------------------------- ### Fetch Nested Relations using Object Notation Source: https://github.com/vincit/objection.js/blob/main/doc/guide/query-examples.md Presents the same nested relation fetching as the previous example but uses Objection.js's object notation for clarity and flexibility. This method is often more readable for complex graph structures. ```javascript const people = await Person.query().withGraphFetched({ pets: true, children: { pets: true, children: true } }); ``` -------------------------------- ### Start Objection.js Transaction with Callback Source: https://github.com/vincit/objection.js/blob/main/doc/guide/transactions.md Starts a database transaction using Objection.js's `Model.transaction` method. The provided callback function is executed within the transaction context. The transaction is automatically committed if the callback resolves successfully, or rolled back if it throws an error or rejects. ```js await Person.transaction(async trx => { // Here you can use the transaction. // Whatever you return from the transaction callback gets returned // from the `transaction` function. return 'the return value of the transaction'; }); ``` -------------------------------- ### Objection.js: ref() SQL Output Examples Source: https://github.com/vincit/objection.js/blob/main/doc/api/model/static-methods.md These SQL snippets demonstrate the output generated by the `ref()` method in Objection.js, showing how it correctly handles table names and aliases in queries. ```sql select "persons".* from "persons" where "persons"."firstName" = 'Jennifer' ``` ```sql select "p".* from "persons" as "p" where "p"."firstName" = 'Jennifer' ``` -------------------------------- ### Objection.js Raw SQL with Named Placeholders Source: https://github.com/vincit/objection.js/blob/main/doc/api/objection/README.md Illustrates using Objection.js's `raw` helper with named placeholders (`:name:` for identifiers, `:name` for values) and a mapping object for safer and more readable SQL construction. This approach enhances clarity by explicitly naming parameters. ```javascript await Person.query() .select( raw('coalesce(sum(:sumColumn:), 0) as :alias:', { sumColumn: 'age', alias: 'ageSum' }) ) .where( 'age', '<', raw(':value1 + :value2', { value1: 50, value2: 25 }) ); ``` -------------------------------- ### Objection.js: Select with `fn` and `ref` Helpers Source: https://github.com/vincit/objection.js/blob/main/doc/recipes/README.md Provides an alternative to raw SQL strings by using Objection.js's `fn` and `ref` helpers for SQL functions and column references. This snippet achieves the same result as the previous example but with a more structured, helper-based approach. ```js const { fn, ref } = require('objection'); const childAgeSums = await Person.query() .select(fn.coalesce(fn.sum(ref('age')), 0).as('childAgeSum')) .where( fn.concat(ref('firstName'), ' ', ref('lastName')), 'Arnold Schwarzenegger' ) .orderBy(fn('random')); console.log(childAgeSums[0].childAgeSum); ``` -------------------------------- ### Unrelate Movies from Actor (Subquery) Source: https://github.com/vincit/objection.js/blob/main/doc/guide/query-examples.md Illustrates unrelating movies from an actor when the actor is identified via a subquery, such as finding 'Arnold Schwarzenegger'. This method uses a placeholder for the actor's ID, which is resolved when the query is executed. The example provides the JavaScript and corresponding SQL. ```js // Once again, note that we don't await this query. This query // is not executed. It's a placeholder that will be used to build // a subquery when the `relatedQuery` gets executed. const arnold = Person.query().findOne({ firstName: 'Arnold', lastName: 'Schwarzenegger' }); await Person.relatedQuery('movies') .for(arnold) .unrelate() .where('name', 'like', 'Terminator%'); ``` ```sql delete from "persons_movies" where "persons_movies"."personId" in ( select "persons"."id" from "persons" where "firstName" = 'Arnold' and "lastName" = 'Schwarzenegger' ) and "persons_movies"."movieId" in ( select "movies"."id" from "movies" where "name" like 'Terminator%' ) ```