如果这个问题很明显,我很抱歉,但我似乎找不到足够的文档。我可能缺乏关于宁静方法的知识。如何存储具有关系的记录?
我有个地方。我想存储用户在这个地方发布的帖子。所以一个地方可以有很多帖子。一个岗位属于一个地方。
我使用的是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()
进行注释。