2
votes

This is a Swift Vapor question related to the Vapor ValidationSuite and Validator.

My Class has a name variable. I used to declare name as a String. But I wanted to perform validation on this field. So I inherited the attributes of a validated Name field. See the following example code.

class Name: ValidationSuite {
static func validate(input value: String) throws {
let evaluation = OnlyAlphanumeric.self
    && Count.min(5)
    && Count.max(20)
    try evaluation.validate(input: value)
  }
}

The following code shows my class. Interesting points; this inherits from the Model class (as it connects to a database) and uses a Node for the ID. You can see I declared the name variable to conform to a Name type.

final class LedgerUser: Model {
var id: Node?
var name: Name

This generates a couple of "Type of expression is ambiguous without more context". I guess it relates to Node retrieving a string from the mySQL database and not knowing how to cast it into the Name type?

2

2 Answers

2
votes

The syntax for using a validator is like Valid<Name>.

Check out the docs about common usage here: https://vapor.github.io/documentation/guide/validation.html#common-usage

The following code should work:

final class LedgerUser: Model {
    var id: Node?
    var name: Valid<Name>
1
votes

Thanks @Tanner.

For those who hit the same issue - you just pass in the entire request object when you instantiate your class. In the following example look at the shoprequest. This was the bit I was getting wrong. Vapor does the heavy lifting for you. For example:

drop.post("shop")     { shoprequest in

guard let name = shoprequest.data["name"].string else {
    throw Abort.custom(status: .badRequest, message: "Please enter a shop")
}

do {
    var coffeeshop = try CoffeeShop(request: shoprequest)
}
catch let error as ValidationErrorProtocol {
    print(error.message)
    throw Abort.custom(status: .badRequest, message: "Please check your coffee shop name")
}

return "You were a good coffee shop name."
}

So when you TRY to instantiate an CoffeeShop object it validates it against your rules.

class CoffeeShop {
var name: Valid<Name>

init(request: Request) throws {
    name = try request.data["name"].validated()
}
}