Search code examples
enumsvaporvapor-fluent

enum giving error with vapor 4 and fluent


This puzzles me:

I have a model in which I want to use an enum. I first declare the enum:

enum MenuChoices: String, Codable {
    case reachableAt
    case attentionTo
    case reasonVisit
    case reasonProblem
}

Then it is in my fields of the class:

@Enum(key: "menu_choices")
var menuChoices: MenuChoices

I then create it in the database using a migration:

struct CreateUserMenu: Migration {    
func prepare(on database: Database) -> EventLoopFuture<Void> {
    return database.enum("menu_choices")
        .case("reachable_at")
        .case("attention_to")
        .case("reason_visit")
        .case("reason_problem")
        .create()
        .flatMap { menu_choices in
            return database.schema("user_menus")
                .id()
                .field("created_at", .datetime, .required)
                .field("updated_at",.datetime, .required)
                .field("deleted_at",.datetime)
                .field("menu_choices", menu_choices)
                .field("be_nl", .string)
                .field("be_fr", .string)
                .field("en_us", .string)
                .create()
        }
    }
}

So far so good. This migration works and the database looks ok. But when I want to add some data to seed the database in another migration I get an error :

let test = UserMenu( menuChoices: MenuChoices.reachableAt, beNl: "nl", beFr: "fra", enUs: "eng")
let _ = test.save(on: database)

+ App.addUserMenus on default
Would you like to continue?
y/n> y
[ ERROR ] previousError(MySQL error: Server error: Data truncated for column 'menu_choices' at row 1)
Fatal error: Error raised at top level: previousError(MySQL error: Server error: Data truncated for column 'menu_choices' at row 1): file /AppleInternal/BuildRoot/Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-1103.8.25.8/swift/stdlib/public/core/ErrorType.swift, line 200
    USSS-Voyager-II:24yours data$ 

Unfortunately this error doesn’t really help to pinpoint the source of the problem


Solution

  • The problem is that there is no mapping between the swift definition of the enum and the Fluent enum. Putting a string literal value for your swift enum definition that matches the string literal value of the Fluent will fix the problem.

    enum MenuChoices: String, Codable {
        case reachableAt = "reachable_at"
        case attentionTo = "attention_to"
        case reasonVisit = "reason_visit"
        case reasonProblem = "reason_problem"
    }