Laravel Validator "in:" not seeing first element - laravel

I have the following ruleset. The "in:" rules will fail with not found if the first element in the array is entered in the input field. However if 2nd or subsequent elements are selected then the rule fires ok. Has anyone else had this issue? I am using "Laravel 7"
"title": "required|min:2|max:50|regex:/^[a-zA-Z][a-zA-Z ]+$/u",
"target_start_date": "required|date_format:Y-m-d|after_or_equal:today",
"target_finish_date": "required|date_format:Y-m-d|after_or_equal:target_start_date",
"genre": "required|in:[adventure,action,biographical,contemporary,crime,thriller,mystery,fantasy,historical,horror,medical,myths,political,romance,sci_fi,war]",
"visibility": "required|in:[public,friends,public]",
"owner_starts": "required|in:[yes,no,sequence,random]",
"owner_finishes": "required|in:[yes,no,sequence,random]"

That’s not how you specify values for the in rule; you just specify the options as comma-delimited strings. For example:
'visibility' => ['required', 'in:public,friends'],
(I’ve also used the “array” syntax for specifying rules, as it makes each individual validation rule easier to see rather than a long string full of | characters.)
If the available options are stored as an array elsewhere in your application, such as a repository or a configuration file, then you can pass that array of options directly to the “fluent” rule builder as per Charlie’s answer:
'genre' => [
'required',
Rule::in($genres),
],
Be sure to import Illuminate\Validation\Rule if you want to use this approach.

"owner_finishes": "required|in:[yes,no,sequence,random]"
Should be:
use Illuminate\Validation\Rule;
'owner_finishes' => [
'required',
Rule::in(['yes', 'no', 'sequence', 'random']),
],
As the docs says:
Since this rule often requires you to implode an array, the Rule::in method may be used to fluently construct the rule:

Related

Fluent validation: either have both fields with value or both must be empty

I am trying to use fluent validation to validate the following rule:
Rule: Either both LocationLattitude and LocationLongitude must contain
a value or they must both be empty. You cannot have one field with
value and the other empty.
Can someone help me out with this?
This is the code I have written:
RuleFor(ar => ar.LocationLattitude)
.CasCade(CascadeMode.StopFirstFailure);
RuleFor(ar => ar.LocationLongitude)
.CasCade(CascadeMode.StopFirstFailure);

required_without not working with other rules

'person.mail' =>'required_without:person.phone|sometimes|email|unique:persons,mail',
'person.phone' => 'required_without:person.mail|sometimes|regex:/[0-9]/|size:10|unique:persons,phone'
i need to validate phone and mail, one of them is mandatory
when the mail is empty and the phone isn't, the validation fails at the email rule and this goes both ways, when the mail is present and phone empty, it fails at the regex rule
how can i stop validation if value is null?
As the laravel docs state:
In some situations, you may wish to run validation checks against a
field only if that field is present in the input array. To quickly
accomplish this, add the sometimes rule to your rule list.
I get the feeling that you actually do post both person[email] and person[phone], in which case sometimes will instruct validation to continue, since the values will then be empty strings (or maybe null) rather than not present. You can conditionally add rules on other assertions than check whether key x exists by creating your own validator, and use its sometimes() method to create your own assertions:
$v = Validator::make($data, [
'person.email' => 'email|unique:persons,mail',
'person.phone' => 'regex:/[0-9]/|size:10|unique:persons,phone',
]);
$v->sometimes('person.email', 'required', function($input) {
return ! $input->get('person.phone');
});
$v->sometimes('person.phone', 'required', function($input) {
return ! $input->get('person.email');
});
The difference here is that the fields are not by default required. So for example, person.phone may either be empty, or must match your regex. If $input->get('person.email') returns a falsy value, person.phone is required after all.
As a note, I think your regex is wrong. It will pass as soon as any character inside person.phone is a number. I think you're looking for something like this:
'person.phone' => 'regex:/^[0-9]{10}$/|unique:persons,phone'
i worked it around like this, it's not the best way, but it works just fine
after the validation i added
if(empty($request->all()['person']['mail']) && empty($request->all()['person']['phone'])){
$validator->errors()->add('person.mail', 'Mail or phone required');
$validator->errors()->add('person.phone', 'Mail or phone required');
return redirect("admin/people-create")->withInput()->withErrors($validator);
}

Laravel validation no space allowed for username

I have a little problem in laravel validation request. I want to reject username with space like foo bar. I just want to allow foobar without space. Right now my rule is required|unique:user_detail,username. What rule should i use? thanks
Why don't you use alpha_dash rule?
required|alpha_dash|unique:user_detail,username
From the documentation:
The field under validation may have alpha-numeric characters, as well
as dashes and underscores.
And it doesn't allow spaces.
You can extend the validator with your own custom rules:
Validator::extend('without_spaces', function($attr, $value){
return preg_match('/^\S*$/u', $value);
});
Then just use as any other rule:
required|without_spaces|unique:user_detail,username
Checkout the docs on custom validation rules:
https://laravel.com/docs/5.2/validation#custom-validation-rules
You should use regular expression with your validation.
PHP :
required|unique:user_detail,username,'regex:/\s/'
Laravel validation for username or subdomain
"subdomain" => [
"regex:/^[a-zA-Z0-9]+$/",
"required", "min:3","max:20","unique:subdomains",
],
You should use regular expressions with your validation.
Laravel:
'domain' => 'required|max:255|unique:users|regex:/(^[a-zA-Z]+[a-zA-Z0-9\\-]*$)/u',
The assumption is that a username can contain either (only alphabetic letters) or a mixture of (alphabetic letters and numbers).
In that case, the rules below should work.
(for alphabetic letters) -> ['username' => 'alpha'] //eg johndoe
(for alphabetic letters and numbers) -> ['username' => 'alpha_num'] //eg johndoe123

How to access Laravel validation translations

As we know, to use validators and translate messages we need to use field.validatorname with translated text.
So now I have entry.php file with my translation:
return [
'validation' => [
'title.max' => 'some text',
]
];
validator will use this text without a problem. The question is - how to access this text using trans / Lang::get() ?
For example using trans('entry.validation.title.max') won't work. I tried using [] for example trans('entry.validation[title.max]') but it also doesn't work.
The only way it works is using array dereference syntax:
trans('entry.validation')['title.max']
Is there any other way?

How do you stop a MongoDB search from being applied recursively to the key-value tree?

Imagine I have this object (written with Ruby literals) stored in a MongoDB:
{"tags" => ["foo", "bar"],
"jobs" => [{"title" => "Chief Donkey Wrangler", "tags" => ["donkeys"]}] }
Now, I want to search for objects based on the tags on the first level of data, not the second. I can write a query like this (using the Ruby MongoDB library):
things.find("tags" => {"$exists" => "foo"})
This will obviously match the first example, but it will also match an example like this:
{"tags" => ["baz", "bar"],
"jobs" => [{"title" => "Trainee Donkey Wrangler", "tags" => ["donkeys", "foo"]}] }
How do I ensure that I am searching only the top-level of keys? I'm interested in knowing the answer in both JavaScript, Ruby and in a language-agnostic way, as I'd like to use MongoDB as a cross-language store.
Obviously, I could pass a map-reduce function to the datastore to pick out the stuff I'm trying to get, but I'm interested to see if it is supported at a higher level (and to reduce the amount of time I spend writing JavaScript map-reduce functions!)
Actually, the query you specify won't match your second example. To match the second example, you'd do:
things.find({"jobs.tags" => "foo"})
There's no recursive application of the query selector.
You're not using $exists properly. $exists does not allow you to search for a match of a field, it just checks for the existence of such a field. I'm guessing that the Ruby MongoDB library is treating your request for 'foo' as equivalent to true, b/c $exists only accepts true/false as an argument
As #kb points out, you want to use the dot notation to reach into the objects.

Resources