流利的蒸气关系-服务器端Swift
了解如何在模型,父母,孩子和兄弟姐妹之间建立关系。
我们将创建一个小型Web应用程序,了解如何实现Model作为Parent , Children和Siblings之间的关系 。
本文假定您已经对 Vapor 有所了解, 并希望 使用 Fluent 在您的模型之间 建立一些 关系 。 否则,您可以参考 Vapor的Documentation 来设置您的第一个项目 。
列出主人约翰的所有宠物
在第一个教程中,我们将构建一个简单的Web API,以在线添加宠物及其主人信息。 让我们将数据保存到数据库中 ,该数据库可通过路线访问。 我们将通过JSON将数据提供给客户端。
建立关系
关系允许数据库实体之间基于外键的连接。
我们要做的是创建Pet
并将其设置为“ Children”作为所有者 。 这样,我们将能够从一个所有者那里获取所有Pet 。
外键
为使魔术发生,我们需要在Pet上添加一个外键 ,该键将是一个Node类型,该类型将存储Parent的ID,即Node。
var owner_id: Node?
并在数据库中建立关系,请将以下行添加到prepare方法中:
pets.parent(Owner.self, optional: false)
如果您想迁移数据库,请单击“如何使用Vapor的Fluent迁移数据库”的链接。
最后,您的Pet.swift文件应如下所示:
此外,要建立关系,您需要将所有者的ID设置为宠物的owner_id
。
注意:请记住,实体 所有者 将获得一个 id
在 save()
。
我们知道我们其中一位主人的id
为1 ,我们可以设置一条路线来放置Pet
给这个Owner
这让我们发布 上 /pets/owner_id:
响应应如下所示:
{
“ id”:1
“ name”:“ Titu”,
“ owner_id”:1
“ type”:“狗”
}
现在我们已经设置了外键,我们可以得到Pet’s Parent: Owner
。
父母
(属于)
我们可以使用外键和类型获取父级 ,如下所示。
让我们为Pet
添加Extension
如文档中所述:
由于我们正在扩展 Pet
,因此不再需要使用 pet.
在 owner_id
之前 。 此外,由于我们 在方法的返回类型 中提供有关 Owner
的类型信息 ,因此我们不再需要将其作为参数传递。
可查询的对象,这意味着您可以delete()
parent filter()
, filter()
等。
要获取父级,必须调用get()
。
let owner = try pet.owner().get()
孩童
(HasMany,HasOne)
我们可以得到孩子们 :
let children = try owner.children(nil, Pet.self).all()
或添加扩展名:
由于类型信息可以从返回值中清除, Pet.self
不需要将Pet.self
传递给children()
。
这是可查询的对象,因此您可以调用first()
, all()
, filter()
等。
现在,我们可以使用所有者的ID来GET
所有者的Pet 。
能够获得ResponseRepresentable
我们的[Pet]
我们需要为Pet
类型的Sequence
添加扩展名
获取所有所有者/所有者/所有人并在其中饲养宠物。
我们将扩展Owner
并创建自己的makeJSON()
以在其中添加Pets。
缺少一件事,我们仍然需要扩展[Owner]才能调用try owner.query().all().makeJSON()
,提醒一下,我们之前对[Pet]
做过同样的事情,除了这次,我们将不调用owner
makeJSON()
,而是将makeJSON()
放入其中。
最后,它应该如下所示。
更新您的路由以在owner.query().all()
上调用makeJSON()
owner.query().all()
,最终得到:
和响应 :
{
“拥有者”: [
{
“所有者”:{
“ id”:1
“名称”:“约翰”
},
“宠物”:[
{
“ id”:1
“ name”:“ Titu”,
“ owner_id”:1
“ type”:“狗”
}
]
}
]
}
兄弟姐妹
(属于)
Siblings
工作方式不同于Children
或Parent
因为他们需要Pivot
。
例如,假设我们要允许宠物携带多个玩具。 但是我们也希望玩具可以被多只宠物共享。 为此,我们需要一个枢轴实体。
我们首先创建一个Toy
模型。
加
pets_toys
- id
- pet_id
- toy_id
您可以看到数据透视实体pets_toys
或Pivot
。
让我们将便捷方法添加到Pet
。
而Toy
则相反。
要准备与Pivot
的关系,只需在main.swift中将枢轴添加到Droplet
的准备中即可 :
不要忘记运行vapor run prepare ——revert
😉
构建项目时,应使用新表pets_toys
在数据库中准备表
现在已经完成了所有设置,我们将为所有Pet
添加一个Toy
让它通过。
您应该熟悉它,它会创建一个Toy
并将其保存。
在这里,我们得到了所有Pet
。
但是魔术来了。
我们在每个Pet
和先前使用Pivot
创建的Toy
之间创建一个Pivot
Pivot
这将在toy_id
和pet_id
之间创建关系。 如果您print(try pivot.makeNode())
,将会得到类似下面的内容。
object([[id]:Node.Node.number(25),“ pet_id”:Node.Node.number(1),“ toy_id”:Node.Node.number(11)])
object([[id]:Node.Node.number(26),“ pet_id”:Node.Node.number(2),“ toy_id”:Node.Node.number(11)])
object([[id]:Node.Node.number(27),“ pet_id”:Node.Node.number(3),“ toy_id”:Node.Node.number(11)])
如您所见, toy_id = 11
具有三个Siblings
。
最后打印出Toy
和他的Siblings
Pet
瞧!
您可以在Github中找到整个项目。
xGoPox /兽医
兽医–专为教程而设计的项目,显示了模型,父级,子级之间的关系的基本信息…… github.com
我希望你们喜欢这篇文章,我的第一篇。 请不要犹豫地发表评论,给我不好或不好的反馈,非常感谢!
分享&❤。
我非常喜欢与Vapor一起工作,并真诚地鼓励您继续使用它,2017年对于Swift的Server Side来说似乎是一年!