Closed parth391 closed 3 years ago
I've neither used nor tested this behaviour, so not sure if it will work.
Are you able to see what query is actually being run? I would have thought the custom key casting worked similarly to the getRouteKeyName
method on the model, but not sure. I suppose in that scenario it's bypassing the custom cast?
Query running is as bellow:
select * from 'users' where 'uuid' = '418a5383-6134-42fd-bd5d-4d838c3dfe96' and 'users'.'deleted_at' is null limit 1
Even after setting getRouteKeyName as uuid its still not working.
My route
Route::get('users/{user}/edit', 'UsersController@edit')->name('users.edit');
My model
public function getRouteKeyName()
{
return 'uuid';
}
protected $casts = [
'uuid' => EfficientUuid::class,
];
My controller
public function edit(User $user)
{
//
}
@parth391 I think your issue is that the implicit route model binding is taking the UUID string literally, whereas the query needs the binary version of the UUID.
I ran into the exact problem you did. The only way I could fix it was by using explicit route model binding. Add this to your app/Providers/RouteServiceProvider@boot
(updating to your key name and model, of course):
Route::bind('deal', function ($value) {
return \App\Models\Deal::whereUuid($value)->first();
});
The downside is that you have to add those three lines for each and every route bound to that Model.
@michaeldyrynda Is there some other way of referencing the uuid
attribute that we're not seeing? In my idea world, I'd be able to use the string form of the UUID (418a5383-6134-42fd-bd5d-4d838c3dfe96
) in the PHP code and have it automagically cast/convert to the binary form behind the scenes, where I never have to see it.
For example, this does not work, because it is similarly querying with the UUID string instead of the UUID binary.
Deal::whereNotIn('uuid', ['1eaf88f1-dd8d-60ba-9780-080027718adf','906eaba3-1053-43f1-8c04-4be57b08598f'])->get()
[
"query" => "select * from `deals` where `uuid` not in (?, ?)"
"bindings" => [
1 => "1eaf88f1-dd8d-60ba-9780-080027718adf"
2 => "906eaba3-1053-43f1-8c04-4be57b08598f"
]
]
P.S. I came across #89 , and it looks like that issue is very similar to what I'm describing. I do have laravel-efficient-uuid installed, and the Deal model is casting: protected $casts = ['uuid' => EfficientUuid::class];
This isn't working for me, can you see what is wrong:
Route::patch('/{thingl}'...................etc
Thing.php
public function getRouteKeyName()
{
return 'uuid';
}
RouteServiceProvider
Route::bind('thing', function ($value) {
return Thing::whereUuid($value)->first();
});
test
$response = $this->patchJson(route('thing.update', $thing), $thing->toArray());
I get:
"message": "No query results for model [App\Models\Thing] ae92f158-36a4-47c6-8bf4-2308c2a1df04"
I got my binding working by adding this to the model:
public function resolveRouteBinding($value, $field = null)
{
$bytes = Uuid::fromString($value)->getBytes();
return $this->where('uuid', $bytes)->firstOrFail();
}
Hello,
I am trying to use route custom keys & scoping as bellow, but getting 404.
Route::get('users/{user:uuid}/edit', 'UsersController@edit')->name('users.edit')
Is there any to convert uuid to binary uuid, before type-hitting?