Using Laravel Exists Validation with a condition specified with a function - laravel

I have a model where I am attempting to use a exists validation rule like
public static $rules = ['item' => 'exists:items,item,company_id,\Auth::user()->active_company',
'location' => 'exists:locations,location,company_id,\Auth::user()->active_company',
];
This validation rule is always failing.
$validation = Validator::make($this->attributes, static::$rules);
If I modify the rule for the specific user->active_company, it works.
public static $rules = ['item' => 'exists:items,item,company_id,17',
'location' => 'exists:locations,location,company_id,17',
];
It seems as if the function \Auth::user()->active_company isn't being evaluated when the rules are being checked. All of the examples I've seen use a constant rather than a function.
Will this work with laravel validation or do I need to take a different strategy?

The encapsulation of the rules in single quotes means that the contents are taken literally. This means that the validation rule is looking for a company ID which is literally '\Auth::user()->active_company' as opposed to the output of that, perhaps 1 for the sake of example.
See the single quoted strings manual page
There are few ways you could do it:
Break out of the quotes and concatenate the two strings with a period (.)
public static $rules = [
'item' => 'exists:items,item,company_id,'.\Auth::user()->active_company,
'location' => 'exists:locations,location,company_id,'.\Auth::user()->active_company,
];
Write active_company to a variable and break out of the quotes and concatenate the two strings with a period (.)
$activeCo = \Auth::user()->active_company;
public static $rules = [
'item' => 'exists:items,item,company_id,'.$activeCo,
'location' => 'exists:locations,location,company_id,'.$activeCo,
];
Write active_company to a variable and use double quotes as variables are expanded/interpreted inside double ones. "$activeCo" or "{$activeCo}" will work
$activeCo = \Auth::user()->active_company;
public static $rules = [
'item' => "exists:items,item,company_id,{$activeCo}",
'location' => "exists:locations,location,company_id,{$activeCo}",
];

Related

I need to apply validation on the combination of columns in laravel model rule

public static $rules = [
'name' => 'min:3|unique:enterprise,name|required',
'lang_id'=> 'min:1|unique:lang_id',
];
This is rule for separate column validation but I need if either column name or lang_id is different then value should be updated
Use the different validation:
The field under validation must have a different value than field.
public static $rules = [
'name' => 'min:3|unique:enterprise,name|required|different:lang_id',
'lang_id'=> 'min:1|unique:lang_id|different:name',
];
As found in the documentation at https://laravel.com/docs/5.5/validation#rule-different

Laravel Custom Validation Rules should be lowercase?

I have model, and it has several field names, and 'lastName' is among them.
In my FormRequest file, I have rules and messages for this field:
$rules = ['lastName.*' => 'lastName_fail: index'];
$messages = ['lastName.*lastName_fail' => This lastName has different value in DB!'];
When I am submitting a form, filling the 'lastName' field with intentionally 'wrong' value, it doesn't pass validation, and returns error message:
validation.last_name_fail
(which is not what's in $messages).
But when I change $rules and $messages to:
$rules = ['lastName.*' => 'lastname_fail: index'];
$messages = ['lastName.*lastname_fail' => This lastName has different value in DB!'];
(so the actual "rule" is now lowercase "lastname_fail"), it outputs what i want:
This lastName has different value in DB!
from this I may conclude that Laravel's validation rule name may be
only lowercase.
Is it declared anywhere in documentation?
If so, maybe it helps someone.
It is not mentioned in the documentation. However, there is a naming pattern for both validation rule method name and rule name.
Rule Method Name:
It must have validate prefix and the rest of it must be in Camel Case.
Rule Name:
It will be in lowercase without the validate prefix and each word will be separated by an underscore.
So if you want to add alpha_dash_spaces validation rule then the corresponding method will be named validateAlphaDashSpaces().
Simply parse $request[data] before Validator
use Illuminate\Support\Str;
$request['name_it'] = Str::lower($request['name_it']);
$request['name_en'] = Str::lower($request['name_en']);
$validator = Validator::make($request->all(), [
'name_it' => ['required', 'string', 'max:255', 'unique:categories'],
'name_en' => ['required', 'string', 'max:255', 'unique:categories'],
]);
if ($validator->fails()) {
return redirect()
->back()->withErrors($validator)
->withInput();
}

Seeding validation array

I am creating a lot of questions via a seeder. The format I am doing is this
DB::table('questions')->insert([
'name' => 'questionOne',
'rule' => 'nullable|max:50|regex:/(?=.)^\£?(([1-9][0-9]{0,2}(,[0-9]{3})*)|[0-9]+)?(\.[0-9]{1,2})?$/'
]);
Whereby I provide a field name and a validation rule. I was noticing that when applying the above rule, the validation would fail, stating
preg_match(): No ending delimiter '/' found
I done some research and found out that
When using the regex pattern, it may be necessary to specify rules in
an array instead of using pipe delimiters, especially if the regular
expression contains a pipe character.
As recommended, I changed my seeder to this
DB::table('questions')->insert([
'name' => 'questionOne',
'rule' => ['nullable|max:50|regex:/(?=.)^\£?(([1-9][0-9]{0,2}(,[0-9]{3})*)|[0-9]+)?(\.[0-9]{1,2})?$/']
]);
However, when I try to seed with the above, I get an Array to String conversion error. The way I am applying the validation is like so
$rules = [];
$questions = Question::all();
foreach ($questions as $question) {
if (!empty($question->rule)) {
$rules["questions.{$question->id}"] = $question->rule;
}
}
$this->validate($request, $rules);
Is there any way I can get the above regex to work? One point to note is that only a few questions have this regex, if that matters?
Thanks
When using the regex pattern, it may be necessary to specify rules in an array instead of using pipe delimiters, especially if the regular expression contains a pipe character.
This is referring to the $rules variable passed into $this->validate; your regex pattern contains a pipe character | which interferes with Laravel's ability to split up the rule string into an array internally.
Storing the rules in string format with pipe separators also makes it difficult for you to split them into an array upon retrieval from the DB. I'd recommend storing them as a similarly delineated structure like JSON, which would make your seeder:
DB::table('questions')->insert([
'name' => 'questionOne',
'rule' => json_encode([
'nullable',
'max:50',
'regex:/(?=.)^\£?(([1-9][0-9]{0,2}(,[0-9]{3})*)|[0-9]+)?(\.[0-9]{1,2})?$/'
])
]);
and validation:
$rules = [];
$questions = Question::all();
foreach ($questions as $question) {
if (!empty($question->rule)) {
$rules["questions.{$question->id}"] = json_decode($question->rule, true);
}
}
$this->validate($request, $rules);
You would also want to change the rule column type to JSON in your questions table migration.
To further simplify the code, you could make use of Laravel's attribute casting feature which claims to handle the json_encode/json_decode for you:
protected $casts = [
'rule' => 'array',
];

Laravel 5.2 Validate File Array

I have a form with three fields: title, body and photo[]. I'm trying to validate it so that at least one item is filled in, but I can't seem to get it to work. If I upload a file I still receive an error for title and body.
public function rules()
{
return [
'title' => 'required_without_all:body,photo.*',
'body' => 'required_without_all:title,photo.*',
'photo.*' => 'required_without_all:title,body',
'photo.*' => 'mimes:jpeg,gif,png',
];
}
Update: Jonathan pointed out that I had my rules wrong. I've fixed them and am now using this. It's still not working; when I try to upload a photo I get the error message that the other fields are required.
public function rules()
{
return [
'title' => 'required_without:body,photo.*',
'body' => 'required_without:title,photo.*',
'photo.*' => 'required_without:title,body|mimes:jpeg,gif,png',
];
}
If you're looking to ensure the photo field is an array then you need 'photo' => 'array' and then you can use 'photo.*' => '' for the other validations of the array's children.
The rules are separated by a pipe character | so if you were going to combine the two in your example it would be 'photo.*' => 'required_without_all:title,body|mimes:jpeg,gif,png',. I don't see you using the pipe to separate rules so I can't be sure you are aware of it.
This may have been where you were going wrong in the first place (two keys in the associative array that are identical) and some kind of precedence taking affect negating one of the rules.
You could try something like this (for the record I think you were on the right track to begin with using required_without_all as this stipulates the need to be required if all of the given fields are missing):
public function rules()
{
return [
'title' => 'required_without_all:body,photo',
'body' => 'required_without_all:title,photo',
'photo' => 'array',
'photo.*' => 'required_without_all:title,body|mimes:jpeg,gif,png',
];
}
Reference

How do the conditions for validation in Laravel

Just sorry for the dumb question , I know what it is in the documentation . But the documentation does not normally understand how to implement it .
Let's say there is a rule :
public function rules()
{
return [
'title' => 'required|max:15',
'author' => 'required|max:15',
];
}
and it is usually used in the form " Edit " , say the user when editing a product , exceeded character limit of 15 , then leave the message " You have exceeded the character limit ."
PS please show a simple example , he 'll take care of that next to nothing.
Looks like you're using FormRequest for validation. In that case you can add another method named messages() to your request class and return the custom messages from there, following is the example:
public function messages()
{
return [
'required' => 'The attribute: field cannot be left blank',
];
The above example will replace the standard error message the attribute: field is required. with our custom message for all occurrences of required rule, where the attribute: denotes the name of the field under validation.
But if you want to further customise it on per field basis. You can use the dot (.) notation like this:
public function messages()
{
return [
'title.required' => 'The Title must be filled',
];
You're looking for this link in the docs.
As the docs say, define an array of messages that map to the rules, and pass them into the validator. Like so
$rules = [ 'title' => 'max:15' ]
$msgs = [ 'max' => 'Exceeded char limit or whatever!' ]
Validator::make($input, $rules, $msgs);

Resources