Closed lasselehtinen closed 6 years ago
It's only set if it was registered manually or you enabled eloquent.
Did you uncomment $app->withEloquent()
?
Alternatively you can register your own presence verifier as validation.presence
in the container.
I have not enabled Eloquent since I have no use for it in this particular project. I guess I could enable it even though I might get a small performance hit.
I am not too familiar with validation internals in Laravel/Lumen. I was just wondering why this validation rule requires Eloquent anyway? The rule seems to be using the query builder syntax so I guess it is coming from somewhere else.
https://github.com/laravel/framework/blob/5.4/src/Illuminate/Validation/Rules/Exists.php
the $app->withEloquent()
method actually enables the query builder too. It's registering the DatabaseServiceProvider, which is required to use the query builder.
Hmm, you are completely sure? Because the app I am building has $app->withFacades()
enabled while $app->withEloquent();
is not and the query builder works just fine.
I guess If you resolve the query builder later it will work because Application::make
checks that it has a binding and lazily registers the database service provider.
The problem is the validation service provider checks if the database service provider is already bound and skips registering the presence verifier if it's not.
So it's not going to register the presence verifier unless you make the database component at least once before using the validator.
Thanks for the the explanation but it goes way over my expertise :) Is this considered a bug or not? For me it does not make sense to require Eloquent for a certain validation rule, even though it is database related.
I had the same issue for my custom validator class in Laravel 5.4. After doing some googling, I kinda fixed it ('RuntimeException: Presence verifier has not been set.' is not bugging me anymore ) by calling 'setPresenceVerifier' method in the constructor of my custom validator class.
function __construct(Validator $validator)
{
$this->validator = $validator;
$this->validator->setPresenceVerifier(app('validation.presence'));
}
Unless I find any other way to fix this, I am sticking with it. Hope this may help. Thank you.
It's pretty old, but I got the same problem, and found a solution. To me it's a bug on Laravel, I'm trying to find a good way to fix it and open a PR to Laravel, but it's another matter.
There is a simple workaround:
You just need to call app('db')
or the DB facade (if you use facades, I don't like them), before creating the validator. In my case, I just included on my app.php:
//$app->withFacades();
//$app->withEloquent();
// Force db parse, to ensure presence validation setup
app('db');
Calling app('db')
is essentially the same thing as enabling $app->withEloquent()
:
It isn't really a bug. If you have not enabled the database component Lumen can't use it for the presence verifier. You can verify that is the case by looking at the line of code I linked previously:
The other workaround is also doing the same thing. Resolving validation.presence
forces db
to resolve.
If Laravel didn't check for the db
binding before registering the presence verifier it would force everyone to load the database component, even if they weren't using it.
The docs should probably be updated to state that the exists
and unique
rules require uncommenting $app->withEloquent()
.
You'll indeed need to uncomment the $app->withEloquent()
rule. Feel free to make a PR against the docs if you think that'll be more clear 👍
I am having same issue with lumen 8 and $app->withEloquent()
enabled and any of the suggestions up did not help but validation works if I use $this->validate($request,['email'=>'unique:users'])
but it gives error if I try it by dependency injecting Illuminate\Validation\Factory
class, is there a bug about it ?
@esinanturan try injecting Illuminate\Contracts\Validation\Factory
instead.
The reason is, the validator is registered as validator
. Lumen aliases this to Illuminate\Contracts\Validation\Factory
, but it doesn't register an alias for Illuminate\Validation\Factory
.
So when you try to inject Illuminate\Validation\Factory
it doesn't use the container binding from the ValidationServiceProvider
; instead it tries to autowire which skips the presence verifier code in the service provider.
In general it's a good idea to stick to the contracts listed in the docs. If you try injecting a class there's no guarantee that class has a container binding.
I am creating a manual validator like this:
The entry exists in the database, but I am getting the following error: