## Fluent Model Extensions ### FieldsProvidingModel #### How to stop suffering from string literals in Fluent Models' Fields Allows to create Model's fields as an enum and then safely use it without hassling with string literals and suffering from fat fingers. ```swift extension User: FieldsProvidingModel { enum Fields: String, FieldKeyRepresentable { case username } } final class User: Model, Content { static let schema = "users" @ID(key: .id) var id: UUID? @Field(key: Fields.username.key) var username: String? } extension User: InitMigratableSchema { static func prepare(on schemaBuilder: SchemaBuilder) -> EventLoopFuture { return schemaBuilder .id() .field(Fields.username.key, .string) .create() } } ``` ### InitMigratableSchema #### How to stop suffering from Fluent Models' initial migrations boilerplate Easy-breazy stuff for creating initial migrations in three simple steps. 1. Make your model conform to InitMigratableSchema protocol, by implementing static prepare(...) method (almost as usual) ```swift extension User: InitMigratableSchema { static func prepare(on schemaBuilder: SchemaBuilder) -> EventLoopFuture { return schemaBuilder .id() .field(Fields.username.key, .string) .create() } } ``` 2. Add initial migration for the model in your configuration file: ```swift func configureDatabaseInitialMigrations(_ app: Application) { app.migrations.add(User.createInitialMigration()) } ``` ### SiblingRepresentable #### How to stop suffering from Siblings pivot models boiler plate Short-cut for creating many-to-many relations. 1. Define whatever as SiblingRepresentable (enum for example) ```swift extension Todo { enum Relations { enum RelatedTags: SiblingRepresentable { typealias From = Todo typealias To = Tag typealias Through = SiblingModel } } } ``` 2. Add corresponding property with @Siblings property wrapper ```swift final class User: Model, Content { static let schema = "users" @ID(key: .id) var id: UUID? @Siblings(through: Relations.RelatedTags.through, from: \.$from, to: \.$to) var relatedTags: [Tag] } ``` 3. Add initial migration for pivot Fluent model representing the sibling after related models: ```swift private func configureDatabaseInitialMigrations(_ app: Application) { app.migrations.add(Todo.createInitialMigration()) app.migrations.add(Tag.createInitialMigration()) app.migrations.add(Todo.Relations.RelatedTags.Through.createInitialMigration()) } ``` 4. Profit! No need to feel pain from pivot models manual creation any more.