我有一大堆Fluent (Vapor 4)模型,它们都有一个父字段,如下所示:
final class Location: Model, Content {
// .. bunch of other properties
@Parent(key: FieldKeys.campaign)
var campaign: Campaign
}
现在,我想做一个可以应用于所有这些模型的协议,就像这样:
protocol HasCampaignId: Model {
var _campaign: ParentProperty<Self, Campaign> { get }
func belongsToCampaign(_ campaignID: Campaign.IDValue) throws -> Self
}
extension HasCampaignId {
func belongsToCampaign(_ campaignID: Campaign.IDValue) throws -> Self {
if self._campaign.id != campaignID {
throw Abort(.forbidden)
}
return self
}
}
这只是一个方便的小函数,我可以应用于HasCampaignId
模型的任何实例,这就是我的想法。遗憾的是,这不能编译,我得到了错误Property '_campaign' must be declared internal because it matches a requirement in internal protocol 'HasCampaignId'
。我可以将协议设置为公共的,但是我得到了另一个错误:Property '_campaign' must be as accessible as its enclosing type because it matches a requirement in protocol 'HasCampaignId'
。
我可以像这样修改协议:
protocol HasCampaignId: Model {
var campaign: Campaign { get }
func belongsToCampaign(_ campaignID: Campaign.IDValue) throws -> Self
}
extension HasCampaignId {
func belongsToCampaign(_ campaignID: Campaign.IDValue) throws -> Self {
if self.campaign.id != campaignID {
throw Abort(.forbidden)
}
return self
}
}
但这需要我加载campaign关系,这通常不是我想要的-否则它会崩溃并出现致命错误:Fatal error: Parent relation not eager loaded, use $ prefix to access: Parent<Loot, Campaign>(key: campaign_id)
。
我的协议中的campaign
属性也不能应用属性包装。
那么,如何才能有一个需要ParentProperty
字段的协议呢?如何解决编译器错误?
发布于 2021-08-24 03:27:47
从Swift 5.4和5.5开始--你不能。协议中的属性包装器已经被提出,但它们没有实现,而且不可能强制执行。为了流利地绕过这些限制,我们付出了很多努力,但目前还不可能做到你想要做的事情。
https://stackoverflow.com/questions/68897430
复制