Syed Qamar Abbas
Syed Qamar Abbas

Reputation: 3677

Crash on Join with Fluent in Vapor

I have two models and they have one-many relation. Here are my classes.

Booking

final class Booking: PostgreSQLModel {
    /// The unique identifier for this `Todo`.
    var id: Int?

    /// A title describing what this `Todo` entails.
    var user_id: User.ID
    var product_id: Product.ID
    var count: Int

    /// Creates a new `Todo`.
    init(id: Int? = nil, user_id: User.ID, product_id: Product.ID, count: Int) {
        self.id = id
        self.user_id = user_id
        self.product_id = product_id
        self.count = count
    }
}
extension Booking {
    var user: Parent<Booking, User> {
        return parent(\.user_id)
    }
    var product: Parent<Booking, Product> {
        return parent(\.product_id)
    }
}

Product

final class Product: PostgreSQLModel {
    /// The unique identifier for this `Todo`.
    var id: Int?

    /// A title describing what this `Todo` entails.
    var name: String
    var image_url: String
    var description: String
    var price: Int?

    /// Creates a new `Todo`.
    init(id: Int? = nil, name: String, image_url: String, description: String, price: Int) {
        self.id = id
        self.name = name
        self.image_url = image_url
        self.description = description
        self.price = price
    }
}
extension Product {
    var bookings: Children<Product, Booking> {
        return children(\.product_id)
    }
}

Now i want to fetch all bookings of a user and with each booking i want to fetch the product information as well. So for this i have tried to join Booking and Product table but this throws an exception.

Fatal error: 'try!' expression unexpectedly raised an error: ⚠️ CoreError: Parent<Booking, Product> does not conform to ReflectionDecodable. - id: CoreError.ReflectionDecodable : file /BuildRoot/Library/Caches/com.apple.xbs/Sources/swiftlang_Fall2018/swiftlang_Fall2018-1000.11.42/src/swift/stdlib/public/core/ErrorType.swift, line 184 Program ended with exit code: 9

Here is my code for join.

let booking = Booking.query(on: req).join(\Product.bookings, to:\Booking.product).filter(\.user_id == userID).decode(BookingM.self).all()

Upvotes: 0

Views: 286

Answers (1)

Caleb Kleveter
Caleb Kleveter

Reputation: 11494

First off, with the query that you have, you don't need to join the the Product table, because you never query on it or decode it.

Your join statement:

.join(\Product.bookings, to:\Booking.product)

Is incorrect. Instead of joining the Product.bookings property, you should join to the Product.id property, because the product's ID is what the Booking.product property contains.

So your Fluent query should look something like this:

let booking = Booking.query(on: req).join(\Booking.product, to:\Product.id).filter(\.user_id == userID).all()

I removed the .decoding call because the query already decodes the the query result too Booking.

To use your bookings property, your query would look like this:

let booking = product.bookings.query(on: req).filter(\Booking.user_id == userID).all()

Upvotes: 1

Related Questions