0
# Model System
1
2
LoopBack's comprehensive model system provides data modeling, validation, relationships, and persistence capabilities through the Model and PersistedModel base classes, along with a registry system for model management.
3
4
## Capabilities
5
6
### Model Creation and Management
7
8
Create and configure models with properties, validations, and relationships.
9
10
```javascript { .api }
11
/**
12
* Create a new model class
13
* @param {string} name - Model name
14
* @param {Object} properties - Model properties definition
15
* @param {Object} options - Model configuration options
16
* @param {string} options.base - Base model to extend from
17
* @param {Object} options.relations - Model relationships
18
* @param {Object} options.validations - Validation rules
19
* @param {Object} options.settings - Model settings
20
* @returns {Function} Model constructor
21
*/
22
loopback.createModel(name, properties, options);
23
24
/**
25
* Alternative config object approach
26
* @param {Object} config - Model configuration
27
* @param {string} config.name - Model name
28
* @param {Object} config.properties - Properties definition
29
* @param {Object} config.relations - Relationships
30
* @param {Object} config.base - Base model name
31
* @returns {Function} Model constructor
32
*/
33
loopback.createModel(config);
34
35
/**
36
* Configure an existing model
37
* @param {Function} ModelCtor - Model constructor to configure
38
* @param {Object} config - Configuration to apply
39
* @param {DataSource} config.dataSource - Data source to attach to
40
* @param {Object} config.relations - Relations to add/update
41
*/
42
loopback.configureModel(ModelCtor, config);
43
44
/**
45
* Find a model by name
46
* @param {string} modelName - Model name to find
47
* @returns {Function|null} Model constructor or null if not found
48
*/
49
loopback.findModel(modelName);
50
51
/**
52
* Get a model by name (throws if not found)
53
* @param {string} modelName - Model name to get
54
* @returns {Function} Model constructor
55
* @throws {Error} If model not found
56
*/
57
loopback.getModel(modelName);
58
59
/**
60
* Find model by base model type
61
* @param {Function} modelType - Base model constructor
62
* @returns {Function} Subclass if found, or base class
63
*/
64
loopback.getModelByType(modelType);
65
```
66
67
**Usage Examples:**
68
69
```javascript
70
// Create a basic model
71
const Book = loopback.createModel('Book', {
72
title: { type: String, required: true },
73
author: String,
74
isbn: { type: String, index: true },
75
publishedDate: Date,
76
price: Number
77
});
78
79
// Create model with relationships and options
80
const Author = loopback.createModel('Author', {
81
name: { type: String, required: true },
82
email: { type: String, index: { unique: true } },
83
bio: String
84
}, {
85
relations: {
86
books: {
87
type: 'hasMany',
88
model: 'Book',
89
foreignKey: 'authorId'
90
}
91
},
92
validations: {
93
email: { format: 'email' }
94
}
95
});
96
97
// Alternative config approach
98
const Review = loopback.createModel({
99
name: 'Review',
100
properties: {
101
rating: { type: Number, min: 1, max: 5 },
102
comment: String,
103
createdAt: { type: Date, default: Date.now }
104
},
105
relations: {
106
book: {
107
type: 'belongsTo',
108
model: 'Book',
109
foreignKey: 'bookId'
110
}
111
}
112
});
113
114
// Configure existing model
115
loopback.configureModel(Book, {
116
dataSource: loopback.memory(),
117
relations: {
118
reviews: {
119
type: 'hasMany',
120
model: 'Review',
121
foreignKey: 'bookId'
122
}
123
}
124
});
125
```
126
127
### Base Model Class
128
129
The foundation Model class provides event system, validation, and basic model functionality.
130
131
```javascript { .api }
132
/**
133
* Base Model constructor
134
* @param {Object} data - Initial model data
135
*/
136
function Model(data);
137
138
// Static methods
139
/**
140
* Extend the model to create a subclass
141
* @param {string} className - Name for the new model class
142
* @param {Object} properties - Properties for the new model
143
* @param {Object} settings - Settings for the new model
144
* @returns {Function} New model constructor
145
*/
146
Model.extend(className, properties, settings);
147
148
/**
149
* Setup the model (called automatically)
150
*/
151
Model.setup();
152
153
/**
154
* Define a remote method on the model
155
* @param {string} name - Method name
156
* @param {Object} options - Remote method options
157
* @param {Object} options.accepts - Input parameters
158
* @param {Object} options.returns - Return value description
159
* @param {Object} options.http - HTTP configuration
160
*/
161
Model.remoteMethod(name, options);
162
163
/**
164
* Disable a remote method
165
* @param {string} name - Method name to disable
166
* @param {boolean} isStatic - Whether method is static
167
*/
168
Model.disableRemoteMethod(name, isStatic);
169
170
/**
171
* Register before remote hook
172
* @param {string} name - Remote method name or pattern
173
* @param {Function} fn - Hook function
174
*/
175
Model.beforeRemote(name, fn);
176
177
/**
178
* Register after remote hook
179
* @param {string} name - Remote method name or pattern
180
* @param {Function} fn - Hook function
181
*/
182
Model.afterRemote(name, fn);
183
184
/**
185
* Register after remote error hook
186
* @param {string} name - Remote method name or pattern
187
* @param {Function} fn - Hook function
188
*/
189
Model.afterRemoteError(name, fn);
190
191
/**
192
* Check access permission for context
193
* @param {Object} token - Access token
194
* @param {*} modelId - Model instance ID
195
* @param {Object} sharedMethod - Shared method
196
* @param {Object} ctx - Access context
197
* @param {Function} callback - Callback function
198
*/
199
Model.checkAccess(token, modelId, sharedMethod, ctx, callback);
200
201
/**
202
* Get the attached application
203
* @param {Function} callback - Callback function
204
*/
205
Model.getApp(callback);
206
207
// Instance methods
208
/**
209
* Check if model instance is valid
210
* @param {Function} callback - Callback function
211
*/
212
model.isValid(callback);
213
214
/**
215
* Trigger model hooks
216
* @param {string} actionName - Action name
217
* @param {Function} work - Work function
218
* @param {*} data - Hook data
219
* @param {Function} callback - Callback function
220
*/
221
model.trigger(actionName, work, data, callback);
222
```
223
224
### PersistedModel Class
225
226
Extends Model with database operations and CRUD functionality.
227
228
```javascript { .api }
229
/**
230
* PersistedModel constructor (extends Model)
231
* @param {Object} data - Initial model data
232
*/
233
function PersistedModel(data);
234
235
// Instance methods
236
/**
237
* Save the model instance
238
* @param {Object} options - Save options
239
* @param {Function} callback - Callback function
240
*/
241
instance.save(options, callback);
242
243
/**
244
* Delete the model instance
245
* @param {Function} callback - Callback function
246
*/
247
instance.destroy(callback);
248
249
/**
250
* Update a single attribute
251
* @param {string} name - Attribute name
252
* @param {*} value - New value
253
* @param {Function} callback - Callback function
254
*/
255
instance.updateAttribute(name, value, callback);
256
257
/**
258
* Update multiple attributes
259
* @param {Object} data - Attributes to update
260
* @param {Function} callback - Callback function
261
*/
262
instance.updateAttributes(data, callback);
263
264
/**
265
* Replace all attributes
266
* @param {Object} data - New attribute values
267
* @param {Function} callback - Callback function
268
*/
269
instance.replaceAttributes(data, callback);
270
271
/**
272
* Reload instance from database
273
* @param {Function} callback - Callback function
274
*/
275
instance.reload(callback);
276
277
/**
278
* Check if instance is new (not saved)
279
* @returns {boolean} True if new record
280
*/
281
instance.isNewRecord();
282
283
/**
284
* Set the instance ID
285
* @param {*} val - ID value
286
*/
287
instance.setId(val);
288
289
/**
290
* Get the instance ID
291
* @returns {*} ID value
292
*/
293
instance.getId();
294
295
/**
296
* Get the ID property name
297
* @returns {string} ID property name
298
*/
299
instance.getIdName();
300
```
301
302
### Static CRUD Methods
303
304
Standard database operations available on PersistedModel classes.
305
306
```javascript { .api }
307
/**
308
* Create new model instance(s)
309
* @param {Object|Object[]} data - Data for new instance(s)
310
* @param {Function} callback - Callback function
311
*/
312
Model.create(data, callback);
313
314
/**
315
* Update or insert model instance
316
* @param {Object} data - Instance data (must include ID for updates)
317
* @param {Function} callback - Callback function
318
*/
319
Model.upsert(data, callback);
320
321
/**
322
* Find existing instance or create new one
323
* @param {Object} filter - Filter to find existing instance
324
* @param {Object} data - Data for new instance if not found
325
* @param {Function} callback - Callback function
326
*/
327
Model.findOrCreate(filter, data, callback);
328
329
/**
330
* Replace existing instance or create new one
331
* @param {Object} data - Instance data (must include ID)
332
* @param {Function} callback - Callback function
333
*/
334
Model.replaceOrCreate(data, callback);
335
336
/**
337
* Update or insert with where condition
338
* @param {Object} where - Where conditions for matching existing instance
339
* @param {Object} data - Data for new instance if not found
340
* @param {Function} callback - Callback function
341
*/
342
Model.upsertWithWhere(where, data, callback);
343
344
/**
345
* Replace instance by ID
346
* @param {*} id - Instance ID
347
* @param {Object} data - New instance data
348
* @param {Function} callback - Callback function
349
*/
350
Model.replaceById(id, data, callback);
351
352
/**
353
* Find model instances
354
* @param {Object} filter - Query filter
355
* @param {Object} filter.where - Where conditions
356
* @param {Object} filter.include - Relations to include
357
* @param {string|string[]} filter.fields - Fields to select
358
* @param {number} filter.limit - Limit results
359
* @param {number} filter.skip - Skip results
360
* @param {string|Object} filter.order - Sort order
361
* @param {Function} callback - Callback function
362
*/
363
Model.find(filter, callback);
364
365
/**
366
* Find single model instance
367
* @param {Object} filter - Query filter (same as find)
368
* @param {Function} callback - Callback function
369
*/
370
Model.findOne(filter, callback);
371
372
/**
373
* Find model instance by ID
374
* @param {*} id - Instance ID
375
* @param {Object} filter - Additional filter options
376
* @param {Function} callback - Callback function
377
*/
378
Model.findById(id, filter, callback);
379
380
/**
381
* Check if instance exists
382
* @param {*} id - Instance ID
383
* @param {Function} callback - Callback function
384
*/
385
Model.exists(id, callback);
386
387
/**
388
* Count model instances
389
* @param {Object} where - Where conditions
390
* @param {Function} callback - Callback function
391
*/
392
Model.count(where, callback);
393
394
/**
395
* Update model instances
396
* @param {Object} where - Where conditions
397
* @param {Object} data - Data to update
398
* @param {Function} callback - Callback function
399
*/
400
Model.update(where, data, callback);
401
402
/**
403
* Update all matching instances (alias for update)
404
* @param {Object} where - Where conditions
405
* @param {Object} data - Data to update
406
* @param {Function} callback - Callback function
407
*/
408
Model.updateAll(where, data, callback);
409
410
/**
411
* Delete instance by ID
412
* @param {*} id - Instance ID
413
* @param {Function} callback - Callback function
414
*/
415
Model.destroyById(id, callback);
416
417
/**
418
* Delete all matching instances
419
* @param {Object} where - Where conditions
420
* @param {Function} callback - Callback function
421
*/
422
Model.destroyAll(where, callback);
423
```
424
425
**Usage Examples:**
426
427
```javascript
428
// Create instances
429
Book.create({
430
title: 'The Great Gatsby',
431
author: 'F. Scott Fitzgerald',
432
isbn: '978-0-7432-7356-5'
433
}, (err, book) => {
434
console.log('Created:', book.id);
435
});
436
437
// Find with filter
438
Book.find({
439
where: { author: { like: '%Fitzgerald%' } },
440
include: 'reviews',
441
limit: 10,
442
order: 'publishedDate DESC'
443
}, (err, books) => {
444
console.log('Found books:', books.length);
445
});
446
447
// Update instances
448
Book.updateAll(
449
{ author: 'F. Scott Fitzgerald' },
450
{ author: 'Francis Scott Fitzgerald' },
451
(err, info) => {
452
console.log('Updated:', info.count);
453
}
454
);
455
```
456
457
### Change Tracking and Replication
458
459
Methods for tracking changes and replicating data between models.
460
461
```javascript { .api }
462
/**
463
* Create a change stream for real-time updates
464
* @param {Object} options - Stream options
465
* @param {Function} callback - Callback function
466
*/
467
Model.createChangeStream(options, callback);
468
469
/**
470
* Get changes since a checkpoint
471
* @param {number} since - Checkpoint ID
472
* @param {Object} filter - Optional filter
473
* @param {Function} callback - Callback function
474
*/
475
Model.changes(since, filter, callback);
476
477
/**
478
* Replicate changes to another model
479
* @param {number} since - Checkpoint ID
480
* @param {Function} targetModel - Target model constructor
481
* @param {Object} options - Replication options
482
* @param {Function} callback - Callback function
483
*/
484
Model.replicate(since, targetModel, options, callback);
485
486
/**
487
* Get the Change model for this model
488
* @returns {Function} Change model constructor
489
*/
490
Model.getChangeModel();
491
492
/**
493
* Get source ID for replication
494
* @param {Function} callback - Callback function
495
*/
496
Model.getSourceId(callback);
497
```
498
499
## Model Registry
500
501
```javascript { .api }
502
/**
503
* Model registry for managing models and data sources
504
*/
505
class Registry {
506
/**
507
* Create new registry instance
508
*/
509
constructor();
510
511
/**
512
* Registry methods (same as loopback static methods)
513
*/
514
createModel(name, properties, options);
515
configureModel(ModelCtor, config);
516
findModel(modelName);
517
getModel(modelName);
518
getModelByType(modelType);
519
createDataSource(name, options);
520
memory(name);
521
}
522
```
523
524
## Model Configuration Types
525
526
```javascript { .api }
527
/**
528
* Model property definition
529
*/
530
interface PropertyDefinition {
531
type: Function; // Property type (String, Number, Date, etc.)
532
required?: boolean; // Whether property is required
533
default?: any; // Default value
534
index?: boolean | Object; // Index configuration
535
unique?: boolean; // Unique constraint
536
min?: number; // Minimum value (numbers)
537
max?: number; // Maximum value (numbers)
538
length?: number; // String length
539
format?: string; // Validation format
540
}
541
542
/**
543
* Model relationship definition
544
*/
545
interface RelationDefinition {
546
type: string; // Relationship type: hasMany, belongsTo, hasOne, etc.
547
model: string; // Related model name
548
foreignKey?: string; // Foreign key property
549
through?: string; // Through model for many-to-many
550
as?: string; // Relationship alias
551
options?: Object; // Additional relationship options
552
}
553
554
/**
555
* Model validation definition
556
*/
557
interface ValidationDefinition {
558
[propertyName: string]: {
559
presence?: boolean;
560
length?: { min?: number; max?: number };
561
format?: string | RegExp;
562
inclusion?: { in: any[] };
563
exclusion?: { in: any[] };
564
uniqueness?: boolean;
565
custom?: Function;
566
};
567
}
568
```