如何插入具有关系的记录



如果这个问题很明显,我很抱歉,但我似乎找不到足够的文档。我可能缺乏关于宁静方法的知识。如何存储具有关系的记录?

我有个地方。我想存储用户在这个地方发布的帖子。所以一个地方可以有很多帖子。一个岗位属于一个地方。

我使用的是Aqueduct 3.0预发布版。

我有以下型号:

place.dart

class Place extends ManagedObject<_Place> implements _Place {}
class _Place {
@primaryKey
int id;
@Column(unique: true)
String name;
ManagedSet<Post> posts;
}

后期

import 'package:places_api/model/place.dart';
import 'package:places_api/places_api.dart';
class Post extends ManagedObject<_Post> implements _Post {}
class _Post {
@primaryKey
int id;
@Column()
String text;
@Relate(#posts)
Place place;
}

我试图保存帖子,但只能存储一个place对象,而不能存储place_id。显然,下面的post查询不起作用,因为只有values.place对象,而没有values.place_id属性。它是否打算加载该位置,然后将所有帖子存储到其中?

同样,如果没有关系,我无法存储place_id,因为Aqueduct似乎将_视为特殊的东西。我不能使用带有下划线的数据库属性吗?

有什么例子可以解释这一点吗?

@Operation.post()
Future<Response> createPost() async {
final body = request.body.asMap();
final query = new Query<Post>(context)
..values.place_id = body['place_id']
..values.text = body['text'];
final insertedPost = await query.insert();
return new Response.ok(insertedPost);
}

目前我正在发送以下正文作为POST:

{
"place_id": 1,
"text": "My post here"
}

至以下URL:http://localhost:8888/posts

寄这样的东西会更好吗?

{
"text": "My post here"
}

收件人URL:http://localhost:8888/place/1/posts

然后先把这个地方拿来,然后把邮件放在那里?

当表示为JSON时,关系始终是列表或对象。在您的情况下:

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

这允许客户端应用程序解析代码保持一致——相关对象始终是对象,而不是合成字段(例如place_id(。底层数据库通过使用下划线连接关系名称及其主键名称来命名列place_id,但这是API未公开的实现细节。

插入对象时,会插入外键,因为它们是表中的一列。因此,你可以这样写你的操作方法:

@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);
}

如果您使用示例JSON和此代码,您将得到以下SQL查询:INSERT INTO _post (text, place_id) VALUES ('text', 1)

插入关系的"has"端时,必须将相关对象作为单独的查询插入。更新/插入查询只会在单个表上设置/插入值。如果这对您的API有意义,您可能需要在以下位置张贴JSON:

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

插入此对象图的代码可能如下所示:

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();
});
});

其他几个小注释:asMap已被移除,并替换为as<T>decode<T>。如果不添加任何标志,也不需要@Column注释。表定义类型中声明的所有字段都是数据库列。瞬态字段在ManagedObject子类中声明,如果希望它们成为API曲面的一部分,则可以用@Serialize()进行注释。

最新更新