Giter Club home page Giter Club logo

eloquent-eager-limit's Introduction

Eloquent Eager Limit

CI Code Coverage Scrutinizer Code Quality Latest Stable Version Total Downloads License

Important

The package's code has been merged into Laravel 11+ and eager loading limits are now supported natively.

This Laravel Eloquent extension allows limiting the number of eager loading results per parent using window functions.

Supports Laravel 5.5–10.

Compatibility

  • MySQL 5.7+
  • MySQL 5.5~5.6: Due to a bug in MySQL, the package only works with strict mode disabled.
    In your config/database.php file, set 'strict' => false, for the MySQL connection.
  • MariaDB 10.2+
  • PostgreSQL 9.3+
  • SQLite 3.25+: The limit is ignored on older versions of SQLite. This way, your application tests still work.
  • SQL Server 2008+

Installation

composer require staudenmeir/eloquent-eager-limit:"^1.0"

Use this command if you are in PowerShell on Windows (e.g. in VS Code):

composer require staudenmeir/eloquent-eager-limit:"^^^^1.0"

Versions

Laravel Package
10.x 1.8
9.x 1.7
8.x 1.6
7.x 1.5
6.x 1.4
5.8 1.3
5.5–5.7 1.2

Usage

Use the HasEagerLimit trait in both the parent and the related model and apply limit()/take() to your relationship:

class User extends Model
{
    use \Staudenmeir\EloquentEagerLimit\HasEagerLimit;

    public function posts()
    {
        return $this->hasMany('App\Post');
    }
}

class Post extends Model
{
    use \Staudenmeir\EloquentEagerLimit\HasEagerLimit;
}

$users = User::with(['posts' => function ($query) {
    $query->latest()->limit(10);
}])->get();

Improve the performance of HasOne/HasOneThrough/MorphOne relationships by applying limit(1):

class User extends Model
{
    use \Staudenmeir\EloquentEagerLimit\HasEagerLimit;

    public function latestPost()
    {
        return $this->hasOne('App\Post')->latest()->limit(1);
    }
}

class Post extends Model
{
    use \Staudenmeir\EloquentEagerLimit\HasEagerLimit;
}

$users = User::with('latestPost')->get();

You can also apply offset()/skip() to your relationship:

class User extends Model
{
    use \Staudenmeir\EloquentEagerLimit\HasEagerLimit;

    public function posts()
    {
        return $this->hasMany('App\Post');
    }
}

class Post extends Model
{
    use \Staudenmeir\EloquentEagerLimit\HasEagerLimit;
}

$users = User::with(['posts' => function ($query) {
    $query->latest()->offset(5)->limit(10);
}])->get();

Package Conflicts

Contributing

Please see CONTRIBUTING and CODE OF CONDUCT for details.

eloquent-eager-limit's People

Contributors

bonzai avatar crishoj avatar gdebrauwer avatar mpyw avatar niekvelde avatar staudenmeir avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

eloquent-eager-limit's Issues

Eloquent Eager Limiting Doesn't Work Inside Scopes

There appears to be a limitation which prevents the package from intercepting limits set in global scopes. I was hoping to be able to use a global scope to clean up some of my API's controllers.

For instance:

return new AreaCollection(Area::on($database)->where($request->filter['areas'])->limit($request['areas'] ?? 100)->get());

Becomes:

// Controller method

return new AreaCollect(Area::on($database)->get());

// GlobalScopes

static::addGlobalScope('filters', function (Builder $builder) {
    $builder->where(request()->filter[Str::plural(strtolower(class_basename(static::class)))] ?? []);
});

static::addGlobalScope('limit', function (Builder $builder) {
    $builder->limit(request()->limit[Str::plural(strtolower(class_basename(static::class)))] ?? 100);
});

This allows me to clean up my controllers and enforce behavior across all of my resources by including these as traits. It would be nice if these global scopes would utilize eager limiting, but it seems that they perform the default behavior unless I limit directly in the controller rather than the global scopes.

I'll spend some more time looking at this tonight, but I figure someone on this project is probably a much more experienced programmer and will know immediately why this works this way.

staudenmeir/eloquent-eager-limit v1.0 requires illuminate/database ~5.5.29|5.6.*|5.7.*

I recently upgraded to Laravel 5.8 and had to remove this package to be able to upgrade. After upgrading, I tried to install this package and experienced the same issue. I'm pretty sure that this package supports 5.8 (Stated in the comments of the migrations), but I'm unable to know why this occurs.

composer.json:

"require": { "php": "^7.1.3", "fideloper/proxy": "^4.0", "imdbphp/imdbphp": "^6.2", "laravel/framework": "5.8.*", "laravel/tinker": "^1.0", "reinink/advanced-eloquent": "^0.2.0", "staudenmeir/eloquent-eager-limit": "1.0", "tymon/jwt-auth": "^1.0.0-rc.3", "venturecraft/revisionable": "1.*" }

How to work with Polymorphic Relation?

I opened this question on stackoverflow and this package seemed to be a solution in all the eager limit loading laravel related issues.

Since the linked question deals with a polymorphic relationship, I was not sure how to set up the relations correctly for this package to do the eager loading limit for the last 3 guests of a room deal, where the stayable_location (room) is polymorphic.

Any idea what the correct setup would be?

Note: I mentioned you in the SO question @staudenmeir but wasn't sure if you got notified due to the space in your SO username.

issue in nested eager loading

I'm having issue when I try to use nested earger loading with(['comments.user'... the ordering and limit is not working but when I try to remove the .user it's working. When I remove the nested .user I can't show the name of the user when I try to use user->name on my view.

$post = Post::with(['comments.user' => function ($query) {
    $query->latest()->limit(10);
}])->where('id',$id)->first();

see laracasts discussion below:
https://laracasts.com/discuss/channels/eloquent/limiting-eager-loaded-results

FEATURE REQUEST: Allow paginating when eager loading

So far loving this package. Very helpful.
Would it be possible to make use of the paginate function?

 $category = $this->getQuery()->with(['products' => function ($query)  {
            $query->paginate();
        }])->first();

What I am trying to do is show products within a category, but I want to paginate the products.
If this is out of the package's scope, can you suggest a good way to do this?
Not sure if this is a dumb question?

Oracle Support

Is there any progress for supporting Oracel Database?

Thank you :)

error when use offset

$comment = Comment::find($pId)
  $commentList = $comment
                ->childComment()
                ->orderBy('heat', 'desc')
                ->orderBy('id', 'desc')
                ->limit(10)
                ->offset(1)
                ->get();

app/Models/Comment.php

    /**
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
     */
    public function childComment()
    {
        return $this->hasMany(Comment::class, 'comment_id', 'id');
    }

SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'offset 1

Your requirements could not be resolved to an installable set of packages

Your requirements could not be resolved to an installable set of packages

Problem 1

  • Root composer.json requires staudenmeir/eloquent-eager-limit 1.0 -> satisfiable by staudenmeir/eloquent-eager-limit[v1.0].

  • staudenmeir/eloquent-eager-limit v1.0 requires illuminate/database ~5.5.29|5.6.|5.7. -> found illuminate/database[v5 5.33, ..., 5.7.x-dev] but these were not loaded, likely it conflict with another require

Installation failed, reverting ./composer.json and ./composer.lock to their original content

Laravel version x8.0

Polymorphic Many to Many

Hi, does this package support eager loading limits for Polymorphic Many to Many relations?

Thanks

The trait cannot been seen

SQLSTATE[42000]: Syntax error or access violation: 1140 Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP columns is illegal if there is no GROUP BY clause

AWS Aurora Performance

We have very large data sets (the table has 700 million plus records) we are trying to calculate on and this plugin helps tremendously on eager loading the latest relationship.

Weird running into some performance issues with certain queries running on AWS Aurora clusters where the large data set will cause the query to timeout. While we assumed it was the quantity of data causing the timeout when we tried a reproduction of the data on a local MacBook Pro the same query returned in ~1s.

Is there any MySQL config that would be required to improve performance that might be different between local and AWS Aurora?

  • DB cluster is running substantial instances, db.r5.2xlarge which is 8 VCPU and 64 GB ram.
  • The cluster is running MySQL 5.7.12
    • The local machine is running MySQL 5.7.29 not sure if there is a difference in minor versions affecting performance

We're hoping it's just a configuration option in MySQL.

Doesn't work on MariaDB 10.6.4 without disabling strict mode

The readme says

MySQL 5.5~5.6: Due to a bug in MySQL, the package only works with strict mode disabled.
In your config/database.php file, set 'strict' => false, for the MySQL connection.
MariaDB 10.2+

But I'm getting the same behavior for MariaDB 10.2+ as well. I need to disable the strict mode which is something I'd rather not do.

Is that incorrectness in readme or problem in my end?

Performance issue

Thanks for the package! It works! But we've a problem: performance!

It's taking between 6~7 seconds to return the results.

My code:

Route::get('/users', function (Request $request) {
    $data = User::withCount('posts')->with(['posts' => function ($q) {
        $q->latest()->limit(3);
    }])->limit(10)->get();

    return response()->json($data);
});

As I mentioned, it's working as expected. But it's taking a long time to complete the query. Is it a database limitation or the query is malformed by the package?

I've 500,000 fake posts generated just for testing purposes.

I've tested the same example but without the package using lazy load query.

My code:

Route::get('/users', function (Request $request) {
    $data = User::withCount('posts')->limit(10)->get()->map(function ($user) {
        $user->setRelation('posts', $user->posts()->limit(3)->get());
        return $user;
    });

    return response()->json($data);
});

The above code returns the expected result as the package does, but it has returned the results in just 150~200 ms.

Am I missing something to improve performance using the package?

The query still didn't work as expected

Hello , I am having a issue with the package , i am using Laravel 5.6.39.
I have a User and Comment model and trying to limit the number of comments for each user get only 10 comments for all the borrowers. Similar to the issue discussed here laravel/framework#18014.

Using your package, I have included the trait in both the User and Comment model but still, it doesn't work as expected. This is how I make the call in my controller:

User::with(['comments' => function($query) {
                $query->latest('id')->limit(3);
            }])->paginate(50)

Also, can you extend the limit functionality to work on paginate()

Call to undefined method groupLimit() on lumen

Call to undefined method Illuminate\Database\Eloquent\Builder::groupLimit() on lumen 5.8.*

Use the HasEagerLimit trait in both the parent and the related model: post and comment.

code

$result = Post::with(['comment' => function ($query) {
            $query->latest()->limit(10);
        }])->get();

return $result;

HasMany attach

Call to undefined method Staudenmeir\EloquentEagerLimit\Relations\HasMany::attach()

$category->products()->attach($products)

Call to undefined method groupLimit

Laravel 8

  $query = OrganizationView
            ::query()
            ->select(['organizations_view.organization_id', 'organization_type', 'org_name', 'organization_type', 'fio'])
            ->whereHas('claims')
            ->with(['claims' => function ($query) {
                return $query
                    ->select(['claim_id', 'organization_id', 'custom_claim_number'])
                    ->where('rpgu_status_id', '!=', 4)
                    ->orderBy('activation_date', 'desc')
                    ->limit(1);
            }, 'claims.persons' => function ($query) {
                return $query->select([
                    'staff_person_id',
                    'claim_id',
                    'snils',
                    'taxi_licence_number',
                    'car_registration_plate',
                    'car_brand_name',
                    'egisz_vaccinated_received_at',
                    'egisz_recovered_received_at',
                    'covid_flags',
                    'vaccination_date'
                ])->limit(100);
            }
            ]);

This part:

                ])->limit(100);

results in Call to undefined method groupLimit

Ambiguous column on multiple relations

  • Laravel Version: 7.9.2
  • PHP Version: 7.3.17
  • Database Driver: PostgreSQL 10.12

Description:

When there are two or more tables for eager loading, Laravel (PostgreSQL indeed) returns this error:

SQLSTATE[42702]: Ambiguous column: 7 ERROR: column reference "created_at" is ambiguous LINE 1

Which means the created_at column exists in both table.

Steps To Reproduce:

Tables:

Users:
 - id
 - created_at

Posts:
 - id
 - created_at

Videos:
 - id
 - craeted_at

Bloggable (Posts or Videos):
 - id
 - bloggable_type
 - bloggable_id
 - craeted_at

Models:

// app\Models\User.php
public function posts()
{
     return $this->morphedByMany(Post::class, 'bloggable');
}
public function videos()
{
     return $this->morphedByMany(Video::class, 'bloggable');
}

Controller:

User::with(['posts' => function ($query) {
            $query->limit(1);
        }, 'videos' => function ($query) {
            $query->limit(1);
        }])->get();

1140 Mixing of GROUP columns (MIN(),MAX(),COUNT(),...)

Product Model
class Product extends Model { use HasFactory; use \Staudenmeir\EloquentEagerLimit\HasEagerLimit; }

Category Modal
`class Category extends Model
{
use \Staudenmeir\EloquentEagerLimit\HasEagerLimit;

use HasFactory; 
public function products()
{
    return $this->hasMany('App\Models\Product', 'CategoryID', 'CategoryID');
}

}`

Actual Query in Controller
return $products = Category::with(['products' => function ($query) { $query->offset(5)->limit(10); }])->get()

This error shows up in the Laravel Api
SQLSTATE[42000]: Syntax error or access violation: 1140 Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP columns is illegal if there is no GROUP BY clause (SQL: select * from (select *, row_number() over (partition by products.CategoryID) as laravel_row from products where products.CategoryID in (184, 217, 218, 219, 385, 386, 388, 389, 390, 391, 395, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 424, 425, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 448, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 501, 502, 503, 504, 505, 506, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 521, 522, 523, 524, 525, 526, 527, 528, 530, 531, 533, 534, 535, 536, 537, 538, 540, 541, 542, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 682, 683, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 740, 741, 742, 744, 745, 746, 747, 749, 750, 751, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 777, 780, 781, 782, 783, 788, 789, 791, 793, 794, 795, 796, 797, 798, 799, 801, 802, 803, 804, 809, 810, 811, 812, 813, 815, 816, 817, 819, 820, 821, 822, 824, 825, 826, 828, 829, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1038, 1039, 1040, 1041, 1043, 1044, 1045, 1046, 1047, 1048, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1137, 1138)) as laravel_table where laravel_row <= 15 and laravel_row > 5 order by laravel_row)

Syntax error or access violation: 1140 Mixing of GROUP columns with no GROUP columns is illegal if there is no GROUP BY clause

The following result is reported when the query is executed with strict enabled. If strict is disabled the query works properly. I don't use any group_by clause so I have no idea why this query fails...

SQLSTATE[42000]: Syntax error or access violation: 1140 Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP columns is illegal if there is no GROUP BY clause (SQL: select * from (select orders.id, orders.uuid, orders.channel_id, orders.order_nr, orders.first_name, orders.last_name, orders.email, orders.amount, orders.payment_costs, orders.is_demo, orders.created_at, events.organisation_id as laravel_through_key, row_number() over (partition by events.organisation_id order by created_at desc) as laravel_row from orders inner join channels on channels.id = orders.channel_id inner join events on events.id = channels.event_id where channels.deleted_at is null and events.deleted_at is null and events.organisation_id in (2) and payment_status = paid and orders.deleted_at is null) as laravel_table where laravel_row <= 10 order by laravel_row)

useLegacyGroupLimit does not exist

After successfully used this package for one query.
I get this error on another query before. Just don't know why?

File: vendor/laravel/framework/src/Illuminate/Support/Traits/Macroable.php
Line: 103
Message: Method Illuminate\Database\Query\Grammars\MySqlGrammar::useLegacyGroupLimit does not exist.

Limit error!

I got this error!!
ash_error22

  $category_news = Category::whereIn('name_en', ['politecs', 'top-business', 'world-news'])->with(['news' => function($query){
        $query->orderBy('id', 'DESC')->where('status_id', 1)->limit(10);
    }])->get();

Polymorphic relation queries are missing `*_type` field on partitions

From MorphToManyTest:

DB::enableQueryLog();
$posts = Post::with('comments')->get();
echo DB::getQueryLog()[1]['query'];

Expected:

select * from (
  select *, row_number() over (
    partition by "comments"."commentable_id",
                 "comments"."commentable_type"
    order by "created_at" desc
  ) as laravel_row
  from "comments"
  where "comments"."commentable_id" in (1, 2, 3, 4, 5, 6)
    and "comments"."commentable_type" = ?
) as laravel_table
where laravel_row <= 2
order by laravel_row

Actual:

select * from (
  select *, row_number() over (
    partition by "comments"."commentable_id"
    order by "created_at" desc
  ) as laravel_row
  from "comments"
  where "comments"."commentable_id" in (1, 2, 3, 4, 5, 6)
    and "comments"."commentable_type" = ?
) as laravel_table
where laravel_row <= 2
order by laravel_row

Diff:

select * from (
  select *, row_number() over (
    partition by "comments"."commentable_id",
-                "comments"."commentable_type"
    order by "created_at" desc
  ) as laravel_row
  from "comments"
  where "comments"."commentable_id" in (1, 2, 3, 4, 5, 6)
    and "comments"."commentable_type" = ?
) as laravel_table
where laravel_row <= 2
order by laravel_row

How to make it work with WithCount

Hello, how I can make it work with withCount() and orderBy() in a belongsToMany relationship ?

class Article extends Model{

	use \Staudenmeir\EloquentEagerLimit\HasEagerLimit;

	public function categories()
    {
        return $this->BelongsToMany(Category::class);
	}
	
    public function likes()
    {
        return $this->morphMany(Like::class, 'likeable');
    }
}
class Category extends Model{

	use \Staudenmeir\EloquentEagerLimit\HasEagerLimit;

	public function articles()
    {
        return $this->BelongsToMany(Article::class);
    }
}
//This code work 
$categories = Category::has('articles')->with(['articles' => function ($query) {
            $query->with('likes')->select('articles.id', 'name', 'slug')
                ->withCount('likes')->orderBy('likes_count', 'DESC');
 }])->select(['id', 'name', 'slug'])->get();
//this code don't
$categories = Category::has('articles')->with(['articles' => function ($query) {
            $query->with('likes')->select('articles.id', 'name', 'slug')
                ->withCount('likes')->orderBy('likes_count', 'DESC')->limit(10);
 }])->select(['id', 'name', 'slug'])->get();

I can limit but now withCount() and orderBy() don't work anymore

Incompatible with jordanmiguel/laravel-popular using Mysql 8

I upgraded to Mysql 8 from Mysql 5.7, The application was working correctly but now its giving me this SQL error

Column not found: 1054 Unknown column 'visits_count' in 'window order by' (SQL: select * from (select `ads`.*, (select count(*) from `visits` where `ads`.`id` = `visits`.`visitable_id` and `visits`.`visitable_type` = App\\Models\\Ad and `date` >= 2022-03-30) as `visits_count`, row_number() over (partition by `ads`.`category_id` order by `visits_count` desc) as laravel_row from `ads` where  `ads`.`category_id` in (1)) as laravel_table where laravel_row <= 10 order by laravel_row)

My code is this

$category->load(['popularAdsLastWeek' => fn($q) => $q->limit(10)]);

//Model Relation
public function popularAdsLastWeek()
    {
        return $this->ads()->popularWeek();
    }

Can't install on PHP 8

It's not possible to use this on Laravel 6 and PHP 8.

staudenmeir/eloquent-eager-limit:"^1.4" seems to be the version that is compatible with Laravel 6, however its composer.json does not allow PHP 8.

Can you update the requirement to "php": "^7.2|^8.0"?

Does it support hasmanythrough?

i have table
Category many to many comic, has many through chapter
Comic has many chapter
I use

$ category = Category :: where ('slug', $ categorySlug) -> with (['comics.chapters' => function ($ query) {
             $ query-> latest () -> limit (3);
         }]) -> get ();

But how to sort comic table by updated_at?

Duplicate related models aren't filtered with distinct() when combined with eager limit

I've added tests in PR #51 that illustrate the issue.

This particularly affects HasManyDeep relationships.

In my case, I found we can use groupBy() in the following way, to achieve the same effect as distinct() for a BelongsToMany relationship, but I cannot yet say if it's a general solution.

public function cities()
{
    $relation = $this->belongsToMany(City::class, 'user_cities')->limit(2);

    // Filter duplicate results
    return $relation->groupBy(
        $relation->getQualifiedRelatedPivotKeyName(),
        $relation->getQualifiedForeignPivotKeyName()
    );
}

Can't install latest version on Laravel v7.*

Hey

Here are my project dependencies:

{
  "require": {
    "php": "^7.3",
    "ext-json": "*",
    "ext-soap": "*",
    "brozot/laravel-fcm": "dev-master",
    "doctrine/dbal": "~2.3",
    "enniel/laravel-fcm-notification-channel": "dev-master",
    "fideloper/proxy": "^4.0",
    "friendsofphp/php-cs-fixer": "^2.13",
    "fruitcake/laravel-cors": "^2.0",
    "hisorange/browser-detect": "^4.2",
    "intervention/image": "^2.5",
    "kavenegar/laravel": "^1.0",
    "laravel/framework": "^7.0",
    "laravel/helpers": "^1.3",
    "laravel/tinker": "^2.0",
    "league/flysystem-aws-s3-v3": "^1.0",
    "monospice/laravel-redis-sentinel-drivers": "^2.5",
    "morilog/jalali": "3.*",
    "nicolaslopezj/searchable": "^1.10",
    "overtrue/phplint": "^1.1",
    "pbmedia/laravel-ffmpeg": "^7.4",
    "predis/predis": "^1.1",
    "sentry/sentry-laravel": "^1.8",
    "spatie/laravel-activitylog": "^3.14",
    "tucker-eric/eloquentfilter": "^2.3",
    "tymon/jwt-auth": "1.0.*"
  },
}

When I try to install your package, it shows me the following error:

Problem 1
    - Conclusion: remove laravel/framework v7.28.4
    - Conclusion: don't install laravel/framework v7.28.4
    - staudenmeir/eloquent-eager-limit v1.6 requires illuminate/database ^8.0 -> satisfiable by illuminate/database[8.x-dev, v8.0.0, v8.0.1, v8.0.2, v8.0.3, v8.0.4, v8.1.0, v8.10.0, v8.11.0, v8.11.1, v8.11.2, v8.12.0, v8.12.1, v8.12.2, v8.12.3, v8.13.0, v8.14.0, v8.15.0, v8.16.0, v8.16.1, v8.17.0, v8.17.2, v8.18.0, v8.18.1, v8.19.0, v8.2.0, v8.20.0, v8.20.1, v8.21.0, v8.3.0, v8.4.0, v8.5.0, v8.6.0, v8.7.0, v8.7.1, v8.8.0, v8.9.0].
    - staudenmeir/eloquent-eager-limit v1.6.1 requires illuminate/database ^8.0 -> satisfiable by illuminate/database[8.x-dev, v8.0.0, v8.0.1, v8.0.2, v8.0.3, v8.0.4, v8.1.0, v8.10.0, v8.11.0, v8.11.1, v8.11.2, v8.12.0, v8.12.1, v8.12.2, v8.12.3, v8.13.0, v8.14.0, v8.15.0, v8.16.0, v8.16.1, v8.17.0, v8.17.2, v8.18.0, v8.18.1, v8.19.0, v8.2.0, v8.20.0, v8.20.1, v8.21.0, v8.3.0, v8.4.0, v8.5.0, v8.6.0, v8.7.0, v8.7.1, v8.8.0, v8.9.0].
    - don't install illuminate/database 8.x-dev|don't install laravel/framework v7.28.4
    - don't install illuminate/database v8.0.0|don't install laravel/framework v7.28.4
    - don't install illuminate/database v8.0.1|don't install laravel/framework v7.28.4
    - don't install illuminate/database v8.0.2|don't install laravel/framework v7.28.4
    - don't install illuminate/database v8.0.3|don't install laravel/framework v7.28.4
    - don't install illuminate/database v8.0.4|don't install laravel/framework v7.28.4
    - don't install illuminate/database v8.1.0|don't install laravel/framework v7.28.4
    - don't install illuminate/database v8.10.0|don't install laravel/framework v7.28.4
    - don't install illuminate/database v8.11.0|don't install laravel/framework v7.28.4
    - don't install illuminate/database v8.11.1|don't install laravel/framework v7.28.4
    - don't install illuminate/database v8.11.2|don't install laravel/framework v7.28.4
    - don't install illuminate/database v8.12.0|don't install laravel/framework v7.28.4
    - don't install illuminate/database v8.12.1|don't install laravel/framework v7.28.4
    - don't install illuminate/database v8.12.2|don't install laravel/framework v7.28.4
    - don't install illuminate/database v8.12.3|don't install laravel/framework v7.28.4
    - don't install illuminate/database v8.13.0|don't install laravel/framework v7.28.4
    - don't install illuminate/database v8.14.0|don't install laravel/framework v7.28.4
    - don't install illuminate/database v8.15.0|don't install laravel/framework v7.28.4
    - don't install illuminate/database v8.16.0|don't install laravel/framework v7.28.4
    - don't install illuminate/database v8.16.1|don't install laravel/framework v7.28.4
    - don't install illuminate/database v8.17.0|don't install laravel/framework v7.28.4
    - don't install illuminate/database v8.17.2|don't install laravel/framework v7.28.4
    - don't install illuminate/database v8.18.0|don't install laravel/framework v7.28.4
    - don't install illuminate/database v8.18.1|don't install laravel/framework v7.28.4
    - don't install illuminate/database v8.19.0|don't install laravel/framework v7.28.4
    - don't install illuminate/database v8.2.0|don't install laravel/framework v7.28.4
    - don't install illuminate/database v8.20.0|don't install laravel/framework v7.28.4
    - don't install illuminate/database v8.20.1|don't install laravel/framework v7.28.4
    - don't install illuminate/database v8.21.0|don't install laravel/framework v7.28.4
    - don't install illuminate/database v8.3.0|don't install laravel/framework v7.28.4
    - don't install illuminate/database v8.4.0|don't install laravel/framework v7.28.4
    - don't install illuminate/database v8.5.0|don't install laravel/framework v7.28.4
    - don't install illuminate/database v8.6.0|don't install laravel/framework v7.28.4
    - don't install illuminate/database v8.7.0|don't install laravel/framework v7.28.4
    - don't install illuminate/database v8.7.1|don't install laravel/framework v7.28.4
    - don't install illuminate/database v8.8.0|don't install laravel/framework v7.28.4
    - don't install illuminate/database v8.9.0|don't install laravel/framework v7.28.4
    - Installation request for laravel/framework (locked at v7.28.4, required as ^7.0) -> satisfiable by laravel/framework[v7.28.4].
    - Installation request for staudenmeir/eloquent-eager-limit ^1.6 -> satisfiable by staudenmeir/eloquent-eager-limit[v1.6, v1.6.1].

I don't have any explicit requirement about illuminate/database package, also, I can't find the specific version in the lock file. Only these related snippets exist in it:

{
  "name": "laravel/framework",
  "replace": {
    "illuminate/database": "self.version",
    ...
  },
  ...
}
{
  "name": "laravel/tinker",
  "suggest": {
    "illuminate/database": "The Illuminate Database package (^6.0|^7.0|^8.0)."
  },
  ...
}
{
  "name": "nicolaslopezj/searchable",
  "require": {
    "illuminate/database": ">=4.2",
    ...
  },
  ...
}
{
  "name": "spatie/laravel-activitylog",
  "require": {
    "illuminate/database": "^6.0 || ^7.0 || ^8.0",
  },
  ...
}
{
  "name": "tucker-eric/eloquentfilter",
  "require": {
    "illuminate/database": "~5.0|~6.0|~7.0|~8.0",
    ...
  },
  ...
}
{
  "name": "tymon/jwt-auth",
  "require-dev": {
    "illuminate/database": "^5.2|^6|^7|^8",
    ...
  },
  ...
}

Right Syntax while using this as a trait

I have set the restrict mode to false and implemented the trait as described. After applying the trait and using limit, I'm getting the following error:

message: "SQLSTATE[42000]: Syntax error or access violation: 1055 'disma.app_users_comments.id' isn't in GROUP BY (SQL: select * from (select app_users_comments.*, (select count(*) from app_users_comments_voteswhereapp_users_comments.id=app_users_comments_votes.comment_id) as votes_count, (select count(*) from app_users_comments_voteswhereapp_users_comments.id=app_users_comments_votes.comment_idandvote_type= 1) asupvotes_count, (select count(*) from app_users_comments_voteswhereapp_users_comments.id=app_users_comments_votes.comment_idandvote_type= 0) asdownvotes_count, row_number() over (partition by app_users_comments.parent_comment_idorder bycreated_atasc) as laravel_row fromapp_users_commentswherevisible= 1 andapp_users_comments.parent_comment_idin (1, 12, 13) andapp_users_comments.deleted_at is null) as laravel_table where laravel_row <= 10 order by laravel_row)"

Any idea how to solve it?

SQLSTATE[42000]: Syntax error or access violation: 1140 Mixing of GROUP columns (MIN(),MAX(),COUNT(),...)

the above error is displayed after installing and using eloquent-eager-limit package trait to both child and parent model, I want to return limited eager loaded relationship on the polymorphic relationship.

MySQL version: 10.4.22-MariaDB
Laravel version: 8.40
error stack trace: [Link](https://flareapp.io/share/95JqZaB7)

my query
Share::with(['Comment' => function($query){ $query->take(5); }])->where('id',34)->orWhere('id',1)->get();

Comment model
public function Commentable() { return $this->morphTo(); }

Post model
public function Comment() { return $this->morphMany('App\Models\Comment','commentable','commentable_type','commentable_id')->where('type','comment'); }

I hope I have explained better, thanks in advance.

Trait method newBaseQueryBuilder has not been applied, because there are collisions with other trait methods

Hey, i'm using this package https://github.com/grimzy/laravel-mysql-spatial along with eloquent-eager-limit and i'm getting this error:

Symfony \ Component \ Debug \ Exception \ FatalErrorException (E_UNKNOWN) Trait method newBaseQueryBuilder has not been applied, because there are collisions with other trait methods

I'm not very good at Traits yet, so i have no idea how to fix this. Can you help?

HasOne from belongsToMany with limit 1

It's possible to use limit(1) to transform a belongsToMany relation to a single result (currently a collection) ?

Currently I use that

 public function users()
    {
        return $this->morphToMany(User::class, 'roleable', 'user_roles')->withPivot('role')
            ->withTimestamps();
    }

    public function owner()
    {
        return $this->users()->wherePivot('role', 'owner')->limit(1);
    }

    public function getOwnerAttribute()
    {
        return $this->getRelationValue('owner')->first();
    }

    public function toArray()
    {
        return array_merge($this->relationsToArray(), $this->attributesToArray()); // it reverses the two defaults parameters
    }

Organization::find('x')->append('owner')->toJson();

Does not work in MySQL 5.6 and 5.5

It works well only in MySQL 5.7, not in 5.6 and 5.5.

1) Tests\BelongsToManyTest::testEagerLoading
Illuminate\Database\QueryException: SQLSTATE[42000]: Syntax error or access violation: 1463 Non-grouping field 'laravel_row' is used in HAVING clause (SQL: select laravel_table.*, @laravel_row := if(@laravel_partition = `pivot_user_id`, @laravel_row + 1, 1) as laravel_row, @laravel_partition := `pivot_user_id` from (select @laravel_row := 0, @laravel_partition := 0) as laravel_vars, (select `roles`.*, `role_user`.`user_id` as `pivot_user_id`, `role_user`.`role_id` as `pivot_role_id` from `roles` inner join `role_user` on `roles`.`id` = `role_user`.`role_id` where `role_user`.`user_id` in (1, 2) order by `pivot_user_id` asc, `created_at` desc) as laravel_table having laravel_row <= 2 order by laravel_row)
select laravel_table.*, 
       @laravel_row := if(@laravel_partition = `pivot_user_id`, @laravel_row + 1 
                       , 1) as 
       laravel_row, 
       @laravel_partition := `pivot_user_id` 
from   (select @laravel_row := 0, 
               @laravel_partition := 0) as laravel_vars, 
       (select `roles`.*, 
               `role_user`.`user_id` as `pivot_user_id`, 
               `role_user`.`role_id` as `pivot_role_id` 
        from   `roles` 
               inner join `role_user` 
                       on `roles`.`id` = `role_user`.`role_id` 
        where  `role_user`.`user_id` in ( 1, 2 ) 
        order  by `pivot_user_id` asc, 
                  `created_at` desc) as laravel_table 
having laravel_row <= 2 
order  by laravel_row 

Conflict Trait

when i use below traits in a class, there is error

use \Staudenmeir\EloquentEagerLimit\HasEagerLimit;
use \Awobaz\Compoships\Compoships;

Not working withCount

return $query->withCount('mosques')->orderBy('mosques_count','desc')->take(2);
This query giving me below error.

Column not found: 1054 Unknown column 'mosques_count' in 'window order by

Custom pivot alias is throwing an error

I'm trying to use this package with a custom pivot alias like this:

public function licenses(): BelongsToMany
  {
    return $this->belongsToMany('App\License')
      ->using('App\CitizenLicense')
      ->as('status')
      ->withPivot('id')
      ->withTimestamps();
  }

With this code an exception is thrown:

Call to a member function newCollection() on null

Related to the method eagerLoadPivotRelations of the package (the second line):

protected function eagerLoadPivotRelations($models, $pivotAccessor)
    {
        $pivots = Arr::pluck($models, $pivotAccessor);
        $pivots = head($pivots)->newCollection($pivots);
        $pivots->load($this->getPivotEagerLoadRelations($pivotAccessor));
    }

If I remove the as('status') from the relationship, it works fine. Note that I'm using this along with eager-load-pivot-relationship package if it matters.

Result array contains unwanted keys

Hi, thanks for the package.

I see some unwanted keys in result array.

{
"user_id": 6,
"question_id": 1,
"average_score": "5.9167",
"laravel_row": 1,
"@laravel_partition := `question_id`": 1
}

Notice laravel_row and @laravel_partition keys. Can we hide them?

Is this by nature of this package ?

Long query time

I got MariaDB installed on my AWS, and trying to get limited relationship data.

It works fine but my queries runs too long, (i got more than 1m rows on server_stats table)

Here is the query

Screen Shot 2020-03-17 at 17 44 00

This is the controller:

Screen Shot 2020-03-17 at 17 45 57

Models:

Screen Shot 2020-03-17 at 17 46 26

Screen Shot 2020-03-17 at 17 46 19

Any suggestions?

Not working on Plesk

Hi, first of all thanks for this awesome package. I use this to develop a forum. It works when I'm using localhost and when I switch to my Plesk database with below data:

Versie database-server Type database-server
10.1.44 MySQL / MariaDB / Percona

I tried to change the strict to false in config/database.php but that also doesn't work. Do you have a fixing code maybe?

Below is the error code I get:
SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '(partition by `threads`.`forum_id` order by `last_post_date` desc) as laravel_ro' at line 1 (SQL: select * from (select *, row_number() over (partition by `threads`.`forum_id` order by `last_post_date` desc) as laravel_row from `threads` where `threads`.`forum_id` in (1, 2, 3, 4)) as laravel_table where laravel_row <= 1 order by laravel_row)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.