Skip to main content

Overview

This API reference provides comprehensive documentation for all IlanaORM methods, classes, and functionality. Each section includes detailed explanations, parameters, return values, and practical examples.

Quick Reference

Model Operations

MethodDescriptionExample
all()Get all recordsUser.all()
create()Create new recordUser.create({ name: 'John' })
find()Find by primary keyUser.find(1)
findBy()Find by column valueUser.findBy('email', 'john@example.com')
findOrFail()Find by primary key or throwUser.findOrFail(1)
first()Get first matching recordUser.first()
firstOrFail()First record or throwUser.firstOrFail()
firstOrCreate()Get first matching or createUser.firstOrCreate({email: 'john@example.com'}, {name: 'John'})
firstOrNew()Find or new instanceUser.firstOrNew({email: 'john@example.com'}, {name: 'John'})
updateOrCreate()Update existing or create newUser.updateOrCreate({email: 'john@example.com'}, {name: 'John'})
make()Create new instance (not saved)User.make({ name: 'John' })
insert()Insert raw dataUser.insert([{name: 'John'}, {name: 'Jane'}])
insertGetId()Insert and get IDUser.insertGetId({name: 'John'})
upsert()Upsert recordsUser.upsert(data, ['email'], ['name'])
destroy()Delete by IDsUser.destroy([1, 2, 3])
latest()Order by column descUser.latest('created_at')
oldest()Order by column ascUser.oldest('created_at')
query()Get query builderUser.query().where('active', true)
with()Eager load relationsUser.with('posts').get()
withCount()Load relation countsUser.withCount('posts').get()
on()Use specific connectionUser.on('mysql_secondary').get()
withTrashed()Include soft deletedUser.withTrashed().get()
onlyTrashed()Only soft deletedUser.onlyTrashed().get()
withoutTrashed()Exclude soft deletedUser.withoutTrashed().get()
update()Update recorduser.update({ name: 'Jane' })
save()Save modeluser.save()
delete()Delete recorduser.delete()
forceDelete()Force delete (permanent)user.forceDelete()
restore()Restore soft deleteduser.restore()
load()Lazy load relationsuser.load('posts')
loadMissing()Load missing relationsuser.loadMissing('posts', 'roles')
is()Check if same recorduser.is(otherUser)
isNot()Check if different recorduser.isNot(otherUser)
replicate()Clone as new unsaved recorduser.replicate(['slug'])
fresh()Re-fetch from databaseuser.fresh()
increment()Increment a columnuser.increment('login_count')
decrement()Decrement a columnuser.decrement('credits', 5)
withoutEvents()Run callback without eventsUser.withoutEvents(async () => { ... })
prune()Delete all prunable recordsUser.prune()
prunable()Define prunable querystatic prunable() { return this.query().where(...) }
generateUuid()Generate a UUIDUser.generateUuid()
generateUlid()Generate a ULIDUser.generateUlid()
seed()Seed using factoryUser.seed(10)
truncate()Delete all rowsUser.truncate()

Query Builder

MethodDescriptionExample
where()Add WHERE clausequery.where('active', true)
orWhere()Add OR WHERE clausequery.orWhere('role', 'admin')
whereIn()WHERE IN clausequery.whereIn('role', ['admin', 'editor'])
whereNotIn()WHERE NOT IN clausequery.whereNotIn('status', ['banned'])
whereNull()WHERE NULL clausequery.whereNull('deleted_at')
whereNotNull()WHERE NOT NULL clausequery.whereNotNull('email_verified_at')
whereBetween()WHERE BETWEEN clausequery.whereBetween('age', [18, 65])
whereNotBetween()WHERE NOT BETWEEN clausequery.whereNotBetween('age', [65, 100])
whereDate()WHERE date clausequery.whereDate('created_at', '2023-12-01')
whereMonth()WHERE month clausequery.whereMonth('created_at', 12)
whereYear()WHERE year clausequery.whereYear('created_at', 2023)
whereDay()WHERE day clausequery.whereDay('created_at', 15)
whereTime()WHERE time clausequery.whereTime('created_at', '14:30')
whereRaw()Raw WHERE clausequery.whereRaw('age > ? AND salary < ?', [25, 50000])
whereExists()WHERE EXISTS clausequery.whereExists(subquery)
whereNotExists()WHERE NOT EXISTS clausequery.whereNotExists(subquery)
whereJsonContains()JSON contains clausequery.whereJsonContains('preferences', {theme: 'dark'})
whereJsonLength()JSON length clausequery.whereJsonLength('tags', '>', 3)
when()Conditional queryquery.when(condition, callback)
unless()Conditional query (inverse)query.unless(condition, callback)
orderBy()Order resultsquery.orderBy('created_at', 'desc')
orderBySubquery()Order by subquery valuequery.orderBySubquery(q => q.from('votes').count(), 'desc')
latest()Order by column descquery.latest('created_at')
oldest()Order by column ascquery.oldest('created_at')
inRandomOrder()Random orderquery.inRandomOrder()
groupBy()Group by columnsquery.groupBy('role')
having()Having clausequery.having('count', '>', 10)
havingRaw()Raw having clausequery.havingRaw('COUNT(*) > ?', [10])
limit()Limit resultsquery.limit(10)
offset()Offset resultsquery.offset(20)
take()Take results (alias for limit)query.take(10)
skip()Skip results (alias for offset)query.skip(20)
forPage()For pagequery.forPage(2, 15)
select()Select columnsquery.select('id', 'name', 'email')
selectRaw()Raw selectquery.selectRaw('COUNT(*) as count')
addSelect()Add columns or subquery columnsquery.addSelect({ total: q => q.from('orders').count() })
distinct()Distinct resultsquery.distinct()
join()Join tablesquery.join('users', 'posts.user_id', 'users.id')
leftJoin()Left joinquery.leftJoin('profiles', 'users.id', 'profiles.user_id')
rightJoin()Right joinquery.rightJoin('roles', 'users.role_id', 'roles.id')
crossJoin()Cross joinquery.crossJoin('categories')
innerJoin()Inner joinquery.innerJoin('posts', 'users.id', 'posts.user_id')
count()Count recordsquery.count()
sum()Sum columnquery.sum('salary')
avg()Average columnquery.avg('age')
min()Minimum valuequery.min('age')
max()Maximum valuequery.max('salary')
get()Execute queryquery.get()
first()Get first resultquery.first()
firstOrFail()First or throwquery.firstOrFail()
find()Find by IDquery.find(1)
findOrFail()Find or throwquery.findOrFail(1)
pluck()Get column valuesquery.pluck('name')
exists()Check existencequery.exists()
doesntExist()Check non-existencequery.doesntExist()
paginate()Paginate resultsquery.paginate(1, 10)
simplePaginate()Simple paginationquery.simplePaginate(1, 10)
cursorPaginate()Cursor paginationquery.cursorPaginate(10, cursor)
chunk()Process in chunksquery.chunk(100, callback)
lazy()Lazy iterationquery.lazy(500)
cursor()Cursor iterationquery.cursor(1000)
insert()Insert dataquery.insert(data)
insertGetId()Insert and get IDquery.insertGetId(data)
update()Update recordsquery.update(data)
delete()Delete recordsquery.delete()
upsert()Upsert recordsquery.upsert(data, unique, update)
with()Eager load relationsquery.with('posts')
withConstraints()Constrained eager loadingquery.withConstraints('posts', callback)
withCount()Load relation countsquery.withCount('posts')
whereHas()Where has relationquery.whereHas('posts', callback)
whereDoesntHave()Where doesn’t have relationquery.whereDoesntHave('posts')
has()Has relationquery.has('posts', '>', 5)
lockForUpdate()Lock for updatequery.lockForUpdate()
sharedLock()Shared lockquery.sharedLock()
skipLocked()Skip lockedquery.skipLocked()
noWait()No waitquery.noWait()
clone()Clone queryquery.clone()
restore()Bulk restore soft-deleted rowsquery.onlyTrashed().restore()
sole()First or throw if not exactly 1query.sole()
tap()Side-effect callback in chainquery.tap(q => console.log(q.toSQL()))
values()Plain objects, no model wrappingquery.values()
withPendingAttributes()Set scope attribute defaultsquery.withPendingAttributes({ status: 'draft' })
new()New instance with pending attrsquery.published().new({ title: 'Draft' })
create()Create record with pending attrsquery.published().create({ title: 'Post' })

Relationships

MethodDescriptionExample
hasOne()One-to-onethis.hasOne('Profile')
hasMany()One-to-manythis.hasMany('Post')
belongsTo()Inverse relationshipthis.belongsTo('User')
belongsToMany()Many-to-manythis.belongsToMany('Role', 'user_roles')
morphTo()Polymorphic belongs tothis.morphTo('commentable')
morphMany()Polymorphic one-to-manythis.morphMany('Comment', 'commentable')
hasManyThrough()Has many throughthis.hasManyThrough('Post', 'User', 'country_id', 'user_id')
with()Eager loadingUser.with('posts').get()

Method Signatures

Standard Notation

// Method signature format
methodName(requiredParam, (optionalParam = defaultValue), ...restParams);

// Return type notation
// @returns {Promise<Model>} - Returns a Promise that resolves to a Model instance
// @returns {QueryBuilder} - Returns a QueryBuilder instance for chaining
// @returns {Collection} - Returns a Collection of Model instances

Parameter Types

TypeDescriptionExample
stringText value'john@example.com'
numberNumeric value42, 3.14
booleanTrue/falsetrue, false
ObjectPlain object{ name: 'John', age: 30 }
ArrayArray of values[1, 2, 3], ['a', 'b', 'c']
DateDate objectnew Date()
FunctionCallback function(query) => query.where('active', true)
ModelModel instancenew User()
QueryBuilderQuery builder instanceUser.query()

Error Handling

Common Exceptions

// ModelNotFoundException
try {
  const user = await User.findOrFail(999);
} catch (error) {
  if (error.name === "ModelNotFoundException") {
    console.log("User not found");
  }
}

// ValidationException
try {
  const user = await User.create({
    email: "invalid-email",
  });
} catch (error) {
  if (error.name === "ValidationException") {
    console.log("Validation failed:", error.errors);
  }
}

// QueryException
try {
  const users = await User.query().where("invalid_column", "value").get();
} catch (error) {
  if (error.name === "QueryException") {
    console.log("Query failed:", error.message);
  }
}

Error Types

ErrorWhen it occursHow to handle
ModelNotFoundExceptionRecord not found with findOrFail()Check if record exists first
ValidationExceptionModel validation failsValidate input before saving
QueryExceptionSQL query failsCheck column names and syntax
RelationshipExceptionRelationship method failsVerify relationship definitions
ConnectionExceptionDatabase connection failsCheck connection configuration

Response Formats

Single Model

const user = await User.find(1);
// Returns: User instance or null

console.log(user.id); // 1
console.log(user.name); // "John Doe"
console.log(user.email); // "john@example.com"

Collection

const users = await User.all();
// Returns: Collection instance

console.log(users.length); // 5
console.log(users[0].name); // "John Doe"

// Collection methods
users.forEach((user) => console.log(user.name));
const names = users.pluck("name");
const activeUsers = users.filter((user) => user.is_active);

Paginated Results

const result = await User.query().paginate(1, 10);
// Returns: Pagination object

console.log(result.data); // Array of User instances
console.log(result.total); // Total count
console.log(result.currentPage); // 1
console.log(result.nextPage); // 2 (if exists)
console.log(result.perPage); // 10
console.log(result.lastPage); // Last page number
console.log(result.from); // 1
console.log(result.to); // 10

Query Builder

const query = User.query().where("active", true);
// Returns: QueryBuilder instance

// QueryBuilder is chainable
const results = await query.orderBy("name").limit(10).get();

Configuration Options

Model Configuration

class User extends Model {
  // Table configuration
  static table = "users";
  static primaryKey = "id";
  static keyType = "number"; // 'number' | 'string' | 'uuid' | 'ulid'
  static incrementing = true;
  static connection = "mysql";

  // Timestamps
  static timestamps = true;
  static createdAt = "created_at";
  static updatedAt = "updated_at";

  // Soft deletes
  static softDeletes = false;
  static deletedAt = "deleted_at";

  // Mass assignment
  fillable = ["name", "email"];
  guarded = ["id", "password"];

  // Attribute casting
  casts = {
    email_verified_at: "date",
    is_active: "boolean",
    preferences: "json",
  };

  // Hidden attributes
  hidden = ["password", "remember_token"];

  // Appended accessors (available in JSON)
  appends = ["full_name", "avatar_url"];

  // Default values
  attributes = {
    is_active: true,
    role: "user",
  };
}

Query Configuration

// Global query settings
const query = User.query().on("mysql"); // Use specific connection

Conventions

Naming Conventions

ConventionFormatExample
Model namesPascalCase, singularUser, BlogPost, OrderItem
Table namessnake_case, pluralusers, blog_posts, order_items
Column namessnake_casefirst_name, email_verified_at
Relationship methodscamelCaseposts(), userProfile()
Scope methodscamelCase with scope prefixscopeActive(), scopePublished()

File Structure

models/
├── User.js
├── Post.js
└── Comment.js

database/
├── migrations/
│   ├── 20231201_120000_create_users_table.js
│   └── 20231201_130000_create_posts_table.js
├── seeds/
│   ├── UserSeeder.js
│   └── PostSeeder.js
└── factories/
    ├── UserFactory.js
    └── PostFactory.js