[英]Vapor / Fluent - Using Protocol Type in a model
I'm experimenting with a server-side-Swift project using Vapor and Fluent. 我正在尝试使用Vapor和Fluent的服务器端Swift项目。 The idea for this project is to track athletes and their training plans and workouts.
该项目的目的是跟踪运动员及其训练计划和锻炼。 Trying to be protocol-oriented, I have a protocol named "Workout," and then various classes that conform to "Workout" such as "run," "swim," etc.
尝试面向协议,我有一个名为“ Workout”的协议,然后有各种符合“ Workout”的类,例如“ run”,“ swim”等。
Workout.swift: Workout.swift:
import Vapor
import FluentPostgreSQL
protocol Workout {
var title: String { get set }
var duration: Int { get set }
}
And then, for example, Run.swift: 然后,例如,Run.swift:
import Vapor
import FluentPostgreSQL
final class Run: Workout, Codable {
//Conform to Workout
var title: String
var duration: Int
//New Properties
var distance: Double
var id: Int?
init(title: String, duration: Int, distance: Double) {
self.title = title
self.duration = duration
self.distance = distance
}
}
extension Run: PostgreSQLModel {}
extension Run: Content {}
When I create the model for "Training Plan," I would like to have the parameter: 当我为“培训计划”创建模型时,我想使用以下参数:
var workouts = [Workout]?
to allow for any type which conforms to Workout. 允许任何符合Workout的类型。
TrainingPlan.swift: TrainingPlan.swift:
import Vapor
import FluentPostgreSQL
final class TrainingPlan: Codable {
var id: Int?
var title: String
var workouts: [Workout]?
init(title: String) {
self.title = title
}
}
extension TrainingPlan: PostgreSQLModel {}
extension TrainingPlan: Content {}
I get the following errors on TrainingPlan.swift: 我在TrainingPlan.swift上收到以下错误:
Type 'TrainingPlan' does not conform to protocol 'Decodable'
类型“ TrainingPlan”不符合协议“可分解”
Type 'TrainingPlan' does not conform to protocol 'Encodable'
类型“ TrainingPlan”不符合协议“可编码”
Changing Workout.swift to: 将Workout.swift更改为:
protocol Workout: Codable {
var title: String { get set }
var duration: Int { get set }
}
does not resolve the errors. 无法解决错误。
What would be the correct way to handle this with Fluent while still staying protocol-oriented in my data modeling? 在我的数据建模中仍然保持面向协议的情况下,用Fluent处理此问题的正确方法是什么? Thank you!
谢谢!
UPDATE (6/20/18): 更新(6/20/18):
Setting a generic type in TrainingPlan.swift (for types that conform to Workout) resolves the errors about conforming to Encodable / Decodable: 在TrainingPlan.swift中设置通用类型(针对符合Workout的类型)可解决有关符合可编码/可解码的错误:
import Vapor
import FluentPostgreSQL
final class TrainingPlan<W: Workout>: Codable {
var id: Int?
var title: String
var workouts: [W]?
init(title: String) {
self.title = title
}
}
extension TrainingPlan: PostgreSQLModel {}
extension TrainingPlan: Content {}
extension TrainingPlan: Parameter {}
extension TrainingPlan: Migration {}
However, this implementation causes another error with adding TrainingPlan to the database migration in configure.swift: 但是,此实现会在将TrainingPlan添加到configure.swift中的数据库迁移中时引起另一个错误:
migrations.add(model: TrainingPlan.self, database: .psql)
Produces the error: 产生错误:
Generic parameter 'W' could not be inferred
无法推断通用参数“ W”
You need to do 你需要做
swift migrations.add(model: TrainingPlan<ConcreteWorkoutType>.self, database: .psql)
So the compiler knows what the generic type is when compiling your code 因此,编译器在编译代码时就知道泛型是什么
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.