Merge pull request #31 from strongloop/relation-docs
Improve the docs for model relations using diagrams
This commit is contained in:
commit
e4802d38f4
Binary file not shown.
After Width: | Height: | Size: 29 KiB |
|
@ -354,82 +354,114 @@ following syntax:
|
||||||
|
|
||||||
### Relations between models
|
### Relations between models
|
||||||
|
|
||||||
|
#### belongsTo
|
||||||
|
|
||||||
|
A `belongsTo` relation sets up a one-to-one connection with another model, such
|
||||||
|
that each instance of the declaring model "belongs to" one instance of the other
|
||||||
|
model. For example, if your application includes customers and orders, and each order
|
||||||
|
can be placed by exactly one customer.
|
||||||
|
|
||||||
|
![belongsTo](belongs-to.png "belongsTo")
|
||||||
|
|
||||||
|
var Order = ds.createModel('Order', {
|
||||||
|
customerId: Number,
|
||||||
|
orderDate: Date
|
||||||
|
});
|
||||||
|
|
||||||
|
var Customer = ds.createModel('Customer', {
|
||||||
|
name: String
|
||||||
|
});
|
||||||
|
|
||||||
|
Order.belongsTo(Customer);
|
||||||
|
|
||||||
|
|
||||||
|
The code above basically says Order has a reference called `customer` to User using
|
||||||
|
the `customerId` property of Order as the foreign key. Now we can access the customer
|
||||||
|
in one of the following styles:
|
||||||
|
|
||||||
|
|
||||||
|
order.customer(callback); // Get the customer for the order
|
||||||
|
order.customer(); // Get the customer for the order synchronously
|
||||||
|
order.customer(customer); // Set the customer for the order
|
||||||
|
|
||||||
|
|
||||||
#### hasMany
|
#### hasMany
|
||||||
|
|
||||||
A `hasMany` relation builds a one-to-many connection with another model. You'll
|
A `hasMany` relation builds a one-to-many connection with another model. You'll
|
||||||
often find this relation on the "other side" of a `belongsTo` relation. This
|
often find this relation on the "other side" of a `belongsTo` relation. This
|
||||||
relation indicates that each instance of the model has zero or more instances
|
relation indicates that each instance of the model has zero or more instances
|
||||||
of another model. For example, in an application containing users and posts, a
|
of another model. For example, in an application containing customers and orders, a
|
||||||
user has zero or more posts. For example,
|
customer has zero or more orders.
|
||||||
|
|
||||||
// setup relationships
|
![hasMany](has-many.png "hasMany")
|
||||||
User.hasMany(Post, {as: 'posts', foreignKey: 'userId'});
|
|
||||||
// creates instance methods:
|
|
||||||
// user.posts(conds)
|
|
||||||
// user.posts.build(data) // like new Post({userId: user.id});
|
|
||||||
// user.posts.create(data) // build and save
|
|
||||||
|
|
||||||
Define all necessary stuff for `one to many` relation:
|
var Order = ds.createModel('Order', {
|
||||||
|
customerId: Number,
|
||||||
|
orderDate: Date
|
||||||
|
});
|
||||||
|
|
||||||
- foreign key in `many` model
|
var Customer = ds.createModel('Customer', {
|
||||||
- named scope in `one` model
|
name: String
|
||||||
|
});
|
||||||
|
|
||||||
Example:
|
Customer.hasMany(Order, {as: 'orders', foreignKey: 'customerId'});
|
||||||
|
|
||||||
var Book = db.define('Book');
|
|
||||||
var Chapter = db.define('Chapters');
|
|
||||||
|
|
||||||
// Style 1
|
|
||||||
Book.hasMany(Chapter, {as: 'chapters'});
|
|
||||||
|
|
||||||
// Style 2
|
|
||||||
Book.hasMany('chapters', {model: Chapter, foreignKey: 'chapter_id'});
|
|
||||||
|
|
||||||
|
|
||||||
Scope methods created on the base model by hasMany allows to build, create and
|
Scope methods created on the base model by hasMany allows to build, create and
|
||||||
query instances of other class. For example,
|
query instances of other class. For example,
|
||||||
|
|
||||||
Book.create(function(err, book) {
|
customer.orders(filter, callback); // Find orders for the customer
|
||||||
// using 'chapters' scope for build:
|
customer.orders.build(data); // Build a new order
|
||||||
var c = book.chapters.build({name: 'Chapter 1'});
|
customer.orders.create(data, callback); // Create a new order for the customer
|
||||||
// same as:
|
customer.orders.destroyAll(callback); // Remove all orders for the customer
|
||||||
c = new Chapter({name: 'Chapter 1', bookId: book.id});
|
customer.orders.findById(orderId, callback); // Find an order by id
|
||||||
// using 'chapters' scope for create:
|
customer.orders.destroy(orderId, callback); // Delete and order by id
|
||||||
book.chapters.create();
|
|
||||||
// same as:
|
|
||||||
Chapter.create({bookId: book.id});
|
|
||||||
|
|
||||||
// using scope for querying:
|
|
||||||
book.chapters(function() {/* all chapters with bookId = book.id */ });
|
#### hasMany through
|
||||||
book.chapters({where: {name: 'test'}, function(err, chapters) {
|
|
||||||
// all chapters with bookId = book.id and name = 'test'
|
A `hasMany through` relation is often used to set up a many-to-many connection with another model. This relation
|
||||||
|
indicates that the declaring model can be matched with zero or more instances of another model by proceeding through
|
||||||
|
a third model. For example, consider a medical practice where patients make appointments to see physicians. The
|
||||||
|
relevant association declarations could look like this:
|
||||||
|
|
||||||
|
![hasManyThrough](has-many-through.png "hasManyThrough")
|
||||||
|
|
||||||
|
var Physician = ds.createModel('Physician', {name: String});
|
||||||
|
var Patient = ds.createModel('Patient', {name: String});
|
||||||
|
var Appointment = ds.createModel('Appointment', {
|
||||||
|
physicianId: Number,
|
||||||
|
patientId: Number,
|
||||||
|
appointmentDate: Date
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Appointment.belongsTo(Patient);
|
||||||
|
Appointment.belongsTo(Physician);
|
||||||
|
|
||||||
|
Physician.hasMany(Patient, {through: Appointment});
|
||||||
|
Patient.hasMany(Physician, {through: Appointment});
|
||||||
|
|
||||||
#### belongsTo
|
Now the Physician model has a virtual property called `patients`:
|
||||||
A `belongsTo` relation sets up a one-to-one connection with another model, such
|
|
||||||
that each instance of the declaring model "belongs to" one instance of the other
|
|
||||||
model. For example, if your application includes users and posts, and each post
|
|
||||||
can be written by exactly one user.
|
|
||||||
|
|
||||||
Post.belongsTo(User, {as: 'author', foreignKey: 'userId'});
|
physician.patients(filter, callback); // Find patients for the physician
|
||||||
|
physician.patients.build(data); // Build a new patient
|
||||||
|
physician.patients.create(data, callback); // Create a new patient for the physician
|
||||||
|
physician.patients.destroyAll(callback); // Remove all patients for the physician
|
||||||
|
physician.patients.add(patient, callback); // Add an patient to the physician
|
||||||
|
physician.patients.remove(patient, callback); // Remove an patient from the physician
|
||||||
|
physician.patients.findById(patientId, callback); // Find an patient by id
|
||||||
|
|
||||||
The code above basically says Post has a reference called `author` to User using
|
|
||||||
the `userId` property of Post as the foreign key. Now we can access the author
|
|
||||||
in one of the following styles:
|
|
||||||
|
|
||||||
|
|
||||||
post.author(callback); // Get the User object for the post author asynchronously
|
|
||||||
post.author(); // Get the User object for the post author synchronously
|
|
||||||
post.author(user) // Set the author to be the given user
|
|
||||||
|
|
||||||
#### hasAndBelongsToMany
|
#### hasAndBelongsToMany
|
||||||
|
|
||||||
A `hasAndBelongsToMany` relation creates a direct many-to-many connection with
|
A `hasAndBelongsToMany` relation creates a direct many-to-many connection with
|
||||||
another model, with no intervening model. For example, if your application
|
another model, with no intervening model. For example, if your application
|
||||||
includes users and groups, with each group having many users and each user
|
includes users and groups, with each group having many users and each user
|
||||||
appearing in many groups, you could declare the models this way,
|
appearing in many groups, you could declare the models this way,
|
||||||
|
|
||||||
|
![hasAndBelongsToMany](has-and-belongs-to-many.png "hasAndBelongsToMany")
|
||||||
|
|
||||||
User.hasAndBelongsToMany('groups', {model: Group, foreignKey: 'groupId'});
|
User.hasAndBelongsToMany('groups', {model: Group, foreignKey: 'groupId'});
|
||||||
user.groups(callback); // get groups of the user
|
user.groups(callback); // get groups of the user
|
||||||
user.groups.create(data, callback); // create a new group and connect it with the user
|
user.groups.create(data, callback); // create a new group and connect it with the user
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 45 KiB |
Binary file not shown.
After Width: | Height: | Size: 49 KiB |
Binary file not shown.
After Width: | Height: | Size: 30 KiB |
Loading…
Reference in New Issue