Skip to content
This repository was archived by the owner on Apr 20, 2024. It is now read-only.
This repository was archived by the owner on Apr 20, 2024. It is now read-only.

Model with property not present in Request #18

Description

@hsharghi

I have a simple Post model

// Post.swift
final class Post: MySQLModel, Content, Parameter {

    var id: Int?
    var title: String
    var body: String
    var userId: User.ID
}
extension Post: Submittable {
    convenience init(_ create: Post.Create) throws {
        self.init(id: nil, title: create.title, body: create.body, userId: create.userId)
    }
    
    func update(_ update: Post.Submission) throws {
        self.title = update.title ?? self.title
        self.body = update.body ?? self.body
    }
    
    
    struct Submission: SubmissionType {
        let title: String?
        let body: String?
    }
    
    struct Create: Decodable {
        let title: String
        let body: String
        let userId: User.ID
    }
}
extension Post.Submission {
    func fieldEntries() throws -> [FieldEntry<Post>] {
        return try [
            makeFieldEntry(keyPath: \.title, label: "Title", validators: [.count(5...)], isRequired: true),
            makeFieldEntry(keyPath: \.body, label: "Body", validators: [.count(10...)], isRequired: true),
        ]
    }
    
    init(_ post: Post?) {
        title = post?.title
        body = post?.body
    }
}
// PostController.swift
...
  func create(_ req: Request) throws -> Future<Either<Post, SubmissionValidationError>> {       
        let user = try req.authenticated(User.self)
        let userId = user?.id
        return try req.content.decode(Post.Submission.self)
            .createValid(on: req)
            .save(on: req)
            .promoteErrors()
    }

...

userId property needs to be added after a User obtained from token. It can not be sent in request parameters. It was the code before using Submissions

    func create(_ req: Request) throws -> Future<Post> {        
        let user = try req.authenticated(User.self)
        let userId = user?.id
        let postData = try req.content.syncDecode(Post.CreatePost.self)
        return Post(title: postData.title, body: postData.body, userId: userId!).save(on: req)
    }

Not all the properties of a model are sent via the request, some of them have to be calculated or fetched from DB and then use to create/save the model. Something like willCreate or willSave hook will be useful for these kind of situations.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions