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

Eager loading with SoftDeletes (inside with() lambda) #56

Open
shakhinn opened this issue Nov 19, 2024 · 8 comments
Open

Eager loading with SoftDeletes (inside with() lambda) #56

shakhinn opened this issue Nov 19, 2024 · 8 comments
Assignees
Labels
enhancement New feature or request future Task that has lower priority because there is still much to do. orm ORM

Comments

@shakhinn
Copy link

Hi

Is there any way i can load relation with trashed items in with method?

image

@silverqx
Copy link
Owner

silverqx commented Nov 19, 2024

Do you mean this?

auto user = User::withTrashed()->with(...).get()

or something like this should be possible too, but it's doing something different than above and the following it's not eager load:

user->posts()->onlyTrashed().get();
user->posts()->withTrashed().get();

@shakhinn
Copy link
Author

shakhinn commented Nov 19, 2024

I want something like this

user->posts()->withTrashed().get();

But I have ModelsCollection and user->posts()->withTrashed() send query for every user. I want to avoid this by using with method

I haven't found how i can do this.

P.S.
It is awful hack, but now i have written

auto user = User::withTrashed()->with({{"posts", [](auto& query){query.whereRaw(R"(1 = 1 --)")}}}).get()

this sql injection helps me to disable where posts.deleted_at is null that generates by default

@shakhinn
Copy link
Author

UPD
this hack does't work :(
ORM ignores deleted_at column and returns invalid QVariant when i call trashed() method

@silverqx
Copy link
Owner

So you have ModelsCollection of Users and you need to select all Posts that are not trashed eagerly.

You have two choices, this is what I came up with fastly:

auto posts = Post::withTrashed()->whereIn("user_id", users.modelKeys()).get();

or

auto users = User::with({{"posts", [](auto &query)
{
    query.whereNotNull("deleted_at");
}}})->get();

@shakhinn
Copy link
Author

Thanks!

@silverqx
Copy link
Owner

Another solution would be to define the relation like:

std::unique_ptr<HasMany<User, Post>>
postsTrashed()
{
    auto relation = hasMany<Post>(u"post_id"_s);
    relation->withTrashed();
    return relation;
}

@silverqx
Copy link
Owner

silverqx commented Nov 20, 2024

The real problem here is that you should be able to call it like this:

auto users = User::with({{"posts", [](auto &query)
{
    query.withTrashed();
}}})->get();

But this is currently not possible because of this, the relation reference should be passed into this lambda (eg. in this case HasMany<Post> &), but it was tough to do in c++, so I'm passing the basic query builder only QueryBuilder &, so you don't have access to many ORM related methods inside these lambdas.

And if not a relation reference then at least TinyBuilder<Post> & instead of QueryBuilder &, but I think there would be a big difference from a refactor perspective if it will be a relation or TinyBuilder reference.

It would be a valuable refactor. Maybe I should try fixing it. It's not a big deal though. For example, in this case, you can write the thing manually, like query.whereNotNull("deleted_at") instead of query.withTrashed().

@silverqx silverqx self-assigned this Nov 20, 2024
@silverqx silverqx added enhancement New feature or request future Task that has lower priority because there is still much to do. orm ORM labels Nov 20, 2024
@silverqx
Copy link
Owner

I leave it open as it can be enhanced in the future.

@silverqx silverqx reopened this Nov 20, 2024
@silverqx silverqx changed the title Question. Eager Loads with softDeleteing Eager loading with SoftDeletes (inside with() lambda) Nov 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request future Task that has lower priority because there is still much to do. orm ORM
Projects
None yet
Development

No branches or pull requests

2 participants