vapor / fluent-kit

Swift ORM (queries, models, and relations) for NoSQL and SQL databases
MIT License
217 stars 116 forks source link

Cannot fetch fields of @Group submodel. #618

Closed Jean-Daniel closed 2 weeks ago

Jean-Daniel commented 1 month ago

Describe the issue

Trying to use a field from a @Group struct in methods like .field(), .all(), etc fails with an error like Instance method 'all' requires the types 'User' and 'GroupPropertyPath<User, FieldProperty<Pet, String>>.Model' (aka 'Pet') be equivalent.

FluentKit version

1.49.0

Operating system and version

macOS 14.7

Swift version

Apple Swift version 6.0 (swiftlang-6.0.0.9.10 clang-1600.0.26.2)

Steps to reproduce

Create a Vapor project.

Define the following model:

final class Pet: Fields {
    // The pet's name.
    @Field(key: "name")
    var name: String

    // The type of pet.
    @Field(key: "type")
    var type: String

    // Creates a new, empty Pet.
    init() { }
}
final class User: Model {

  static var schema: String = "users"

  @ID(key: .id)
  var id: UUID?

  // The user's nested pet.
  @Group(key: "pet")
  var pet: Pet
}

Try to build a query using that model

func query(req: Request) {
  User.query(on: req.db).filter(\.$pet.$name == "Zizek").all(\.$pet.$name)
}

Build the project.

Outcome

The build fails with the error:

Instance method 'all' requires the types 'User' and 'GroupPropertyPath<User, FieldProperty<Pet, String>>.Model' (aka 'Pet') be equivalent.

Additional notes

No response

0xTim commented 1 month ago

I don't think this is supported behaviour. The @Group is supposed to be all fetched so that we can populate it correctly. I'd say if you need to retrieve specific fields you should look at flattening the model

gwynne commented 2 weeks ago

Tim is correct; the all() method does not support deep keypaths - and while fixing it to do so would be simple, it would also require a source-breaking change and thus can't be done for Fluent 4.