Reputation: 35
This is my code to perform database seeding:
func prepare(on database: Database) -> EventLoopFuture<Void> {
var citySaveResults: [EventLoopFuture<Void>] = []
return User.query(on: database).first().flatMap({ user -> EventLoopFuture<Void> in
guard let userId = user?.id else { return citySaveResults.flatten(on: database.eventLoop).transform(to: ()) }
let cities = [
City(id: UUID(), name: "London", isActive: true, createdAt: Date()),
City(id: UUID(), name: "New York", isActive: true, createdAt: Date()),
City(id: UUID(), name: "San Francisco", isActive: true, createdAt: Date()),
]
for city in cities {
city.plans.append(contentsOf: createPlans(cityId: city.id, userId: userId))
citySaveResults.append(city.save(on: database))
}
return citySaveResults.flatten(on: database.eventLoop) .transform(to: ())
})
}
But it crash in line:
city.plans.append(contentsOf: createPlans(cityId: city.id, userId: userId))
Fatal error: Children relation not eager loaded, use $ prefix to access.
Can someone explain me how to use Eager Loading feature to avoid crash in this situation?
This is my City model:
final class City: Model {
static let schema = "cities"
@ID(key: .id) var id: UUID?
@Field(key: "name") var name: String
@Field(key: "isActive") var isActive: Bool
@Children(for: \Plan.$city) var plans: [Plan]
...
}
Upvotes: 1
Views: 285
Reputation: 5565
Eager loading is for loading only as the name suggests. To save children you need to save the parent first and then save the children separately.
func prepare(on database: Database) -> EventLoopFuture<Void> {
var citySaveResults: [EventLoopFuture<Void>] = []
return User.query(on: database).first().flatMap { user -> EventLoopFuture<Void> in
guard let userId = user?.id else { return citySaveResults.flatten(on: database.eventLoop).transform(to: ()) }
let cities = [
City(id: UUID(), name: "London", isActive: true, createdAt: Date()),
City(id: UUID(), name: "New York", isActive: true, createdAt: Date()),
City(id: UUID(), name: "San Francisco", isActive: true, createdAt: Date()),
]
for city in cities {
let saveResult = city.save(on: database).flatMap {
let plans = createPlans(cityId: city.id, userId: userId)
return plans.save(on: database)
}
citySaveResults.append(saveResult)
}
return citySaveResults.flatten(on: database.eventLoop) .transform(to: ())
}
}
Upvotes: 3