我有一大堆 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
}
}
但这需要我加载活动关系,这通常不是我想要的 - 否则它会因致命错误而崩溃:Fatal error: Parent relation not eager loaded, use $ prefix to access: Parent<Loot, Campaign>(key: campaign_id)
.
我的协议中的campaign
属性也不能应用属性包装器。
那么我怎样才能有一个需要ParentProperty
字段的协议呢?如何解决编译器错误?