Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

querying @OptionalParent relation #8

Closed
jaredh159 opened this issue Jul 21, 2021 · 4 comments
Closed

querying @OptionalParent relation #8

jaredh159 opened this issue Jul 21, 2021 · 4 comments

Comments

@jaredh159
Copy link
Contributor

are you sick of me yet? 😄

OK, so now I'm struggling with a Model that has an @OptionalParent. I spent a while trying to add my own extension to Graphiti.Field to support the OptionalParentProperty property wrapper, akin to what you did with the Siblings wrapper. I figured I'd PR it if I could get it to work.

But... I seem to only sorta be able to get it working. I have a Schema type definition that looks sort of like this:

Type("MyModel", MyModel.self) {
  // [...]
  Field("category", with \.$category) // 👋  <-- here's the @OptionalParent prop
}

The schema won't compile, none of the initializers match an OptionalParent. Below is my attempt at adding another initializer to handle the relationship:

extension Graphiti.Field where Arguments == NoArguments, Context == Request, ObjectType: Model {
  public convenience init<ParentType: Model>(
    _ name: FieldKey,
    with keyPath: KeyPath<ObjectType, OptionalParentProperty<ObjectType, ParentType>>
  ) where FieldType == TypeReference<ParentType?> {
    self.init(
      name.description,
      at: {
        (type) -> (Request, NoArguments, EventLoopGroup) throws -> EventLoopFuture<ParentType?> in
        return { (context: Request, arguments: NoArguments, eventLoop: EventLoopGroup) in
          return type[keyPath: keyPath].get(on: context.db)
        }
      }, as: TypeReference<ParentType?>.self)
  }
}

The new initializer allows my Schema to compile. But then, trying to send a query, I get Cannot complete value of unexpected type "CategoryOptional". Which makes me wonder if I'm just messing up my Schema and resolvers somehow, and if maybe the extension is in fact correct.

The other thing I tried is removing the ? on the fifth line of the extension and the third-to-last line (both places where it says TypeReference<ParentType?>. This also allows the schema to compile, but upon querying I get Cannot return null for non-nullable field MyModel.category.

Any possibility you are able to see at a glance what I've done wrong? Thanks in advance, really appreciate it!

@alexsteinerde
Copy link
Owner

Not at all. I appreciate your enthusiasm and I'm open to support as much as possible!

You have to switch the optional ? from the inner type to the TypeReference type:

// OptionalParent Relationship
extension Graphiti.Field where Arguments == NoArguments, Context == Request, ObjectType: Model {
    
    /// Creates a GraphQL field for an optional one-to-many/one-to-one relationship for Fluent
    /// - Parameters:
    ///   - name: Field name
    ///   - keyPath: KeyPath to the @OptionalParent property
    public convenience init<ParentType: Model>(
        _ name: FieldKey,
        with keyPath: KeyPath<ObjectType, OptionalParentProperty<ObjectType, ParentType>>
    ) where FieldType == TypeReference<ParentType>? {
        self.init(name.description, at: { (type) -> (Request, NoArguments, EventLoopGroup) throws -> EventLoopFuture<Optional<ParentType>> in
            return { (context: Request, arguments: NoArguments, eventLoop: EventLoopGroup) throws -> EventLoopFuture<Optional<ParentType>> in
                return type[keyPath: keyPath].get(on: context.db)  // Get the desired property and make the Fluent database query on it.
            }
        }, as: TypeReference<ParentType>?.self)
    }
}

I'll create an example app and if this is working for me I'll release a new version wit this extension included. Until then you can include it into your code manually.

@jaredh159
Copy link
Contributor Author

Brilliant. I was close! Your code works perfectly. Once again, thanks.

@alexsteinerde
Copy link
Owner

I have published release 2.3.0 that includes the above extension.

@jaredh159
Copy link
Contributor Author

New version works great, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants