Skip to content

Commit

Permalink
Fixed relationship getKey key sorting
Browse files Browse the repository at this point in the history
  • Loading branch information
LaravelFreelancerNL committed Aug 25, 2024
1 parent 9b6e377 commit 2f3dc4d
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 14 deletions.
3 changes: 3 additions & 0 deletions TestSetup/Database/Seeders/HousesSeeder.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public function run()
"_key": "lannister",
"name": "Lannister",
"location_id": "king-s-landing",
"led_by": "TywinLannister",
"en": {
"description": "House Lannister of Casterly Rock is one of the Great Houses of Westeros, one of its richest and most powerful families and one of its oldest dynasties. It was also the royal House of the Seven Kingdoms following the extinction of House Baratheon of King\'s Landing, which had been their puppet House during the War of the Five Kings, for a brief stint of time until House Targaryen took back the Iron Throne in Daenerys Targaryen\'s war for Westeros."
}
Expand All @@ -27,13 +28,15 @@ public function run()
"_key": "stark",
"name": "Stark",
"location_id": "winterfell",
"led_by": "NedStark",
"en": {
"description": "House Stark of Winterfell is a Great House of Westeros and the royal house of the Kingdom of the North. They rule over the vast region known as the North from their seat in Winterfell. It is one of the oldest lines of Westerosi nobility by far, claiming a line of descent stretching back over eight thousand years. Before the Targaryen conquest, as well as during the War of the Five Kings and early on in Daenerys Targaryen\'s war for Westeros, the leaders of House Stark ruled over the region as the Kings in the North."
}
},
{
"_key": "targaryen",
"name": "Targaryen",
"led_by": "DaenerysTargaryen",
"location_id": "dragonstone",
"en": {
"coat-of-arms": "A three-headed dragon breathing flames, red on black (Sable, a dragon thrice-headed gules)",
Expand Down
22 changes: 22 additions & 0 deletions src/Eloquent/Relations/Concerns/IsAranguentRelation.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,28 @@

trait IsAranguentRelation
{
/**
* Get all of the primary keys for an array of models.
*
* @param array<mixed> $models
* @param string|null $key
* @return array<int, int|string>
*/
protected function getKeys(array $models, $key = null)
{
// The original function orders the results associatively by value which means the keys reorder too.
// However, a list of keys with unordered numeric keys will be recognized as an object down the line
// for json casting while we need a list of keys.

$keys = collect($models)->map(function ($value) use ($key) {
return $key ? $value->getAttribute($key) : $value->getKey();
})->values()->unique(null, true)->all();

sort($keys);

return $keys;
}

/**
* Add the constraints for a relationship count query.
*
Expand Down
30 changes: 28 additions & 2 deletions tests/Eloquent/BelongsToManyTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
test('attach', function () {
$child = Character::find('JonSnow');

$lyannaStark = Character::firstOrCreate(
Character::firstOrCreate(
[
'id' => 'LyannaStark',
'name' => 'Lyanna',
Expand All @@ -68,7 +68,7 @@
$child->parents()->attach($lyannaStark);
$child->save();

$reloadedChild = Character::find('JonSnow');
Character::find('JonSnow');
$parents = $child->parents;

expect($parents[0]->id)->toEqual('NedStark');
Expand Down Expand Up @@ -157,3 +157,29 @@
expect($char->tags[1]->pivot->tag_id)->toBeString();
expect($char->tags[1]->pivot->tag_id)->toBe('2');
});

test('with', function () {
$parent = Character::with('children')->find('NedStark');

expect($parent->children)->toHaveCount(5);
expect($parent->children->first()->id)->toEqual('RobbStark');
});

test('with on multiple models', function () {
$characters = Character::with('children')->where('surname', 'Stark')->get();

expect($characters)->toHaveCount(6);
expect($characters[0]->id)->toEqual('NedStark');
expect($characters[0]->children->first()->id)->toEqual('AryaStark');
expect($characters[0]->children)->toHaveCount(5);
expect($characters[1]->id)->toEqual('CatelynStark');
expect($characters[1]->children)->toHaveCount(4);
});

test('load', function () {
$parent = Character::find('NedStark');
$parent->load('children');

expect($parent->children)->toHaveCount(5);
expect($parent->children->first()->id)->toEqual('RobbStark');
});
27 changes: 27 additions & 0 deletions tests/Eloquent/BelongsToTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use LaravelFreelancerNL\Aranguent\Testing\DatabaseTransactions;
use Mockery as M;
use TestSetup\Models\Character;
use TestSetup\Models\House;
use TestSetup\Models\Location;

uses(
Expand Down Expand Up @@ -82,3 +83,29 @@
expect($location->leader)->toBeInstanceOf(Character::class);
expect($location->leader->id)->toEqual('SansaStark');
});


test('with on single model', function () {
$house = House::with('head')->find('lannister');

expect($house->head)->toBeInstanceOf(Character::class);
expect($house->head->id)->toEqual('TywinLannister');
});


test('with on multiple model', function () {
$houses = House::with('head')->get();

expect($houses->count())->toBe(3);
expect($houses->first()->head)->toBeInstanceOf(Character::class);
expect($houses->first()->head->id)->toEqual('TywinLannister');
});


test('load', function () {
$house = House::find('lannister');
$house->load('head');

expect($house->head)->toBeInstanceOf(Character::class);
expect($house->head->id)->toEqual('TywinLannister');
});
8 changes: 8 additions & 0 deletions tests/Eloquent/HasManyTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,11 @@
expect($location->inhabitants->first())->toBeInstanceOf(Character::class);
expect($location->inhabitants->first()->id)->toEqual('NedStark');
});

test('with on multiple models', function () {
$locations = Location::with('inhabitants')->get();

expect($locations->first()->inhabitants->first())->toBeInstanceOf(Character::class);
expect($locations->first()->inhabitants)->toHaveCount(2);
expect($locations[8]->inhabitants)->toHaveCount(0);
});
33 changes: 21 additions & 12 deletions tests/Query/WheresTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -229,20 +229,29 @@
);
});

test('where in', function () {
$builder = getBuilder();
test('whereIn', function () {
$results = DB::table('characters')
->whereIn(
'characters.residence_id',
[
"astapor",
"beyond-the-wall",
"dragonstone",
"king-s-landing",
"riverrun",
"the-red-keep",
"vaes-dothrak",
"winterfell",
"yunkai",
],
)->get();

expect($results)->toHaveCount(33);
expect($results->first()->_id)->toBe('characters/NedStark');
expect($results->first()->residence_id)->toBe('winterfell');
});

$builder->select()
->from('users')
->whereIn('country', ['The Netherlands', 'Germany', 'Great-Britain']);

$this->assertSame(
'FOR userDoc IN users FILTER `userDoc`.`country` IN @'
. $builder->getQueryId()
. '_where_1 RETURN userDoc',
$builder->toSql(),
);
});

test('where integer in raw', function () {
$builder = getBuilder();
Expand Down

0 comments on commit 2f3dc4d

Please sign in to comment.