-
Notifications
You must be signed in to change notification settings - Fork 52
One to one relationship
One to one relationship maps one record in a table to another record in a referred table.
In Jaguar, one-to-one mapping is performed using HasOne
and BelongsTo
annotations. Let us take an user-address example. Each user has an address.
The linked field in the parent model is annotated with HasOne
annotation. In this case, User model is linked to Address model using the address
field. HasOne
takes the bean of the referred table as the argument. In this case, AddressBean
.
HasOne
basically says: "Model User has a one-to-one relationship with model Address by field address".
class User {
@PrimaryKey(length: 50)
String id;
@Column(length: 50)
String name;
@HasOne(AddressBean)
Address address;
User({this.id, this.name, this.address});
}
The foreign key in the referred table should be annotated by BelongsTo
annotation. In this case, userId
is the foreign key that is used to link a user to the address by user's id. BelongsTo
annotation takes the bean of the parent table as the argument. In this case, UserBean
.
BelongsTo
basically says: "Model Address belongs to model User referred by userId field".
class Address {
@PrimaryKey(length: 50)
String id;
@Column(length: 150)
String street;
@BelongsTo(UserBean)
String userId;
Address({this.id, this.street, this.userId});
}
Use refCol
argument in BelongsTo
to specify the matching foreign key column in the parent table. It defaults to id
.
Templates for UserBean
and AddressBean
should be written with members AddressBean addressBean
and UserBean userBean
respectively. The generated bean logic will use these fields to perform operation on the linked tables.
@GenBean()
class UserBean extends Bean<User> with _UserBean {
UserBean(Adapter adapter)
: addressBean = AddressBean(adapter),
super(adapter);
final AddressBean addressBean;
String get tableName => 'oto_simple_user';
}
@GenBean()
class AddressBean extends Bean<Address> with _AddressBean {
UserBean _userBean;
UserBean get userBean => _userBean ??= UserBean(adapter);
AddressBean(Adapter adapter) : super(adapter);
String get tableName => 'oto_simple_address';
}
Besides usual CRUD operations, for models with one-to-one relations, Jaguar generates following logic:
- Cascaded inserts and upserts
- Cascaded deletes
- Cascaded updates
- Auto preload child field
- Manual preload child field
- Find parent by child instance
insert
method of parent bean has cascade
named argument. When this argument is set to true, the child model is automatically inserted into the child table with foreign key filled in.
final user = User()
..id = '1'
..name = 'Teja'
..address = (Address()
..id = '1'
..street = 'Stockholm');
await userBean.insert(user, cascade: true);
remove
method of parent bean has cascade
named argument. When this argument is set to true, the linked child model is automatically removed from the child table by the foreign key.
await userBean.remove('1', cascade: true);
update
method of parent bean has cascade
named argument. When this argument is set to true, the linked child model is automatically updated.
User user = await userBean.find('1', preload: true);
user.name = 'Teja Hackborn';
user.address.street = 'Stockholm, Sweden';
await userBean.update(user, cascade: true);
find
method of parent bean has preload
named argument. When this argument is set to true, the child record is automatically fetched and filled into the parent model when a parent record is queried.
final user = await userBean.find('1', preload: true);
TODO
The child model can be queried by parent's primary key using the generated findBy'ParentModel'
(in this case, findByUser
).
final address = await addressBean.findByUser(user.id);
The preload
argument to findByUser
automatically preloads the child field in parent model.