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

Populate a parent-child relationship after initial query #784

Open
AndrewBoryk opened this issue Jan 19, 2025 · 5 comments
Open

Populate a parent-child relationship after initial query #784

AndrewBoryk opened this issue Jan 19, 2025 · 5 comments
Labels
enhancement New feature or request

Comments

@AndrewBoryk
Copy link

Please summarize your feature request

Being able to populate a parent-child relationship on a record that was already previously queried

Describe the functionality you're seeking in more detail

I want to avoid populating all the fields on a record every single time that I am fetching it.
In addition, sometimes I'd like to be able to just use the User that I get from require during authentication.

The issue is, that if I have a parent-child (or sibling) relationship to that record, it isn't loaded up when I use that require.

So the alternative I have is getting the id from that User, and then querying for that user again to get it populated.

Is there a functionality for this already? If not, it would be nice to populate as needed on a record via query after it's initiatial query

Have you considered any alternatives?

No response

@AndrewBoryk AndrewBoryk added the enhancement New feature or request label Jan 19, 2025
@gwynne
Copy link
Member

gwynne commented Jan 19, 2025

All relation properties (@Parent, @Children, etc.) have a .get() method which loads that relation from the database. Example:

final class User: Model, @unchecked Sendable {
    static let schema = "users"

    @ID
    var id: UUID?

    @Parent(key: "something_id")
    var something: Something
    
    init() {}
}

func someRoute(_ req: Request) async throws -> String {
    let user = try req.auth.require(User.self)
    
    // For convenience, the `get()` method returns the value of the loaded relation;
    // it can also be accessed via the `user.something` property.
    try await user.$something.get(on: req.db)
}

@AndrewBoryk
Copy link
Author

@gwynne Gotcha, that returns the value of the loaded relation, if it is already loaded. But if we want to populate that value, that would work? Or do I need to include the reload parameter? I will test it out, thanks for sharing tho

@gwynne
Copy link
Member

gwynne commented Jan 23, 2025

It will always load and populate the relation if it is not already loaded.

If reload is set to true, it will load and populate the relation even if it has been loaded already.

@duncangroenewald
Copy link

    // For convenience, the `get()` method returns the value of the loaded relation;
    // it can also be accessed via the `user.something` property.
    try await user.$something.get(on: req.db)

When can the value be accessed via the property ? Presumably only after a call to get() has been made ?

@gwynne
Copy link
Member

gwynne commented Feb 21, 2025

Assuming the property had not previously been loaded, yes, that is correct.

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

No branches or pull requests

3 participants