How to insert a record with a Relationship How to insert a record with a Relationship dart dart

How to insert a record with a Relationship


When represented as JSON, a relationship is always a list or an object. In your case:

{  "text": "text",  "place": {    "id": 1  }}

This allows client application parsing code to remain consistent - a related object is always an object, never a synthetic field (e.g., place_id). The underlying database does name the column place_id by joining the relationship name and its primary key name with an underscore, but that's an implementation detail that isn't exposed through the API.

When inserting an object, foreign keys are inserted because they are a column in the table. Therefore, you can write your operation method as so:

@Operation.post()Future<Response> createPost(@Bind.body() Post post) async {  final query = new Query<Post>(context)    ..values = post;  final insertedPost = await query.insert();  return new Response.ok(insertedPost);}

If you were to use the example JSON and this code, you'd get this SQL query: INSERT INTO _post (text, place_id) VALUES ('text', 1).

When inserting the 'has' side of a relationship, you have to insert the related objects as a separate query. An update/insert query will only set/insert values on a single table. If it makes sense for your API, you may want to POST the following place JSON:

{  "name": "Place",  "posts": [    {"text": "text"}  ]}

Your code to insert this object graph might look like:

await context.transaction((t) async {  final q = Query<Place>(t)..values = body;  final insertedPlace = await q.insert();  await Future.wait(body.posts, (p) async {    final postQuery = Query<Post>(t)      ..values = p      ..values.place.id = insertedPlace.id;    return postQuery.insert();  });});

Couple of other small notes: asMap has been removed and replaced with as<T> or decode<T>. You also do not need an @Column annotation if you aren't adding any flags. All fields declared in the table definition type are database columns. Transient fields are declared in the ManagedObject subclass, and can be annotated with @Serialize() if you want them to be a part of the API surface.