Reputation: 241
I'm using Vapor 2 and trying to create non-final model to subclass it. Is it possible? I have following code for abstract model:
class MongoObject: Model, JSONRepresentable {
let storage = Storage()
let creationDate: Date
init() {
creationDate = Date()
}
required init(row: Row) throws {
creationDate = try row.get(KeyPath.creationDate)
}
func makeRow() throws -> Row {
var row = Row()
try row.set(KeyPath.creationDate, creationDate)
return row
}
func makeJSON() throws -> JSON {
var json = JSON()
try json.set(KeyPath.id, id)
try json.set(KeyPath.creationDate, creationDate)
return json
}
}
extension MongoObject: Preparation {
class func prepare(model: Creator) { }
static func prepare(_ database: Database) throws {
try database.create(self) { (builder) in
builder.id()
builder.date(KeyPath.creationDate)
prepare(model: builder)
}
}
static func revert(_ database: Database) throws {
try database.delete(self)
}
}
but got compilation error:
method 'make(for:)' in non-final class 'MongoObject' must return
Self
to conform to protocol 'Parameterizable'
Upvotes: 2
Views: 257
Reputation: 1
I might be too late, but I was having the exact same problem and all I had to do was make the class final.
method 'make(for:)' in non-final class 'MongoObject' must return Self to conform to protocol 'Parameterizable'
Upvotes: 0
Reputation: 930
Your non-final "abstract" model with subclasses is conforming to Parameterizable
as part of the Model
conformance. Parameterizable requires returning Self
. By default this is implemented by reading the entity's id from the path component. The problem you now get is that the compiler can't return Self
for subclasses since it's implemented on a higher model.
The solution is pretty straightforward, you cannot do subclassing here.
Upvotes: 1