yii2 validate only one input field - validation

In my model (In yii2 project) I have two columns called product and code. And the issue is how to validate only code not product. We know that $model->validate() validates entire model. But I need only one input field: code. Is it possible??
More clearly, In my input form I'm using 3 models. How to validate these 3 models in my controller. That's why I'm trying to validate fields of each model separalety? I meant to validate like:
$model->validate(someField)
$anotherModel->(anotherField)
Is this possible??

You can replace this function with model. also show what you have tried so far?
public function rules()
{
return [
[['code', ], 'required'],
];
}

You can use scenario approach in validations rules, and validate only needed fields, by passing appropriate scenario.
More info about scenarios:
http://www.yiiframework.com/doc-2.0/guide-structure-models.html

Related

Accessor overrides custom validation rule

I have created a custom rule to make sure the number is of two decimal places. The database has numbers stored as decimal(19,4). To display the number with only two decimal places, I also have put an accessor in place. Now the problem is that the accessor overrides the custom validation rule.
the relevant part from custom validation rule
public function passes($attribute, $value)
{
$precision = Config::get('accounting.decimal');
return preg_match('/^\d+(\.\d{1,'.$precision.'})?$/',$value);
}
the accessor in model
public function getRateAttribute($value)
{
$precision = Config::get('accounting.decimal');
return round($value, $precision);
}
the validation rule in the livewire component
public function rules()
{
return [
'editing.rate' => ['required', new NumberFormat()],
];
}
Desired behavior:
Whenever a user enters a number with more than two decimal places, it should throw the customer validation error.
Every time the field is used anywhere else to display, it should show the number with two decimal places. For eg: 78.9800 should be displayed as 78.98.
any ideas why this is not happening?
Edit:
Did a little more testing and this seems to be a laravel livewire issue. I am binding data directly to the model property. Because of that, when I edit the field, the accessor is immediately called before validation occurs.
Workaround:
I canceled the data binding to the model property. This solved the issue.
Still is there a better way to use laravel-livewire data binding to model property and use an accssor that would not override the validation rule.

Laravel unique validation must include appended text when validating

I am using the Laravel tenancy package in which there is a domains table in my database and each value in the domain column within this table is appended with .test.co.uk.
When the user enters the URL in the form, they are presented with an input element (shown above) in which they enter a URL/Domain but the .test.co.uk is already appended so the only thing they need to enter is the text that goes before that, e.g. they would enter johnsmith and in the domain column it would store johnsmith.test.co.uk. The problem I have is that I need the validation on this column to be unique but also include the .test.co.uk when performing the validation so that it looks at the value stored in the table because if a user enters johnsmith and there is currently a record in the domains table where the value is johnsmith.test.co.uk then the validation would pass but I need the validation to fail in this scenario. I am currently using a Request class which is extending the FormRequest class and have this:
public function rules()
{
return [
'url' => 'required|string|unique:domains,domain',
];
}
I have also tried a rule object but I don't think a rule object is the correct solution to this problem. Is there a convenient "Laravel" way of doing this?
In your Request class use prepareForValidation()
Docs: https://laravel.com/docs/7.x/validation#prepare-input-for-validation
protected function prepareForValidation()
{
$this->merge([
'url' => $this->url . '.test.co.uk',
]);
}

Laravel Nova conditional fields on form

I'm making a create form for one of my resources using Nova. Some of the fields have conditional relationships to one another.
For example: if "is trial" is selected we must specify a value for "trial end date", but there's no point showing the "end date" field on the page if "is trial" isn't picked. Another example, fields A and B are mutually exclusive.
All of these can easily be enforced with conditional validators in the backend, and I know how to do that. I'm just trying to make an interface that's not confusing.
How can I customize the frontend JS forms for this resource to reflect such conditional relationships?
Its possible using this one
// put this inside **public function fields(Request $request)**
BelongsTo::make('Subcategoria', 'subcategory', 'App\Nova\SubCategory'),
// conditional display
$this->sellerFields(),
//used for conditional seller input
protected function sellerFields()
{
if(\Auth::user()->role == "admin"){
return $this->merge([
BelongsTo::make('Vendedor', 'user', 'App\Nova\User'),
]);
}else{
return $this->merge([]);
}
}

Yii2: How to avoid required fields in a view?

I have a view about holidays where a user uses a form to choose a place to travel and a hotel. It has two models: HolidaysPlaces and HolidaysHotels.
The user have to fill the form in this order using the view:
The user completes the fields called Place and City (related with the HolidaysPlaces model).
The user checked a checkbox if he/she wants to choose a hotel. It able a field called Hotel (related with HolidaysHotels model).
The user completes that field.
The user press a Create button.
The controller receives and saves both models.
But the problem is when the user doesn't select the checkbox (number 2 of the list): The Hotel fieldis still required (with the red asterisk as defined in its model file). So the Create button doesn't work in this case.
How can I disabled the required feature?
Add a scenario for this case in your HolidaysHotels model, and include only the fields that you want checked.
Example: If you have 3 fields name, date and age that are required, create a scenario for two only, and set the scenario in the controller. Only those two fields will be checked.
In model:
public function scenarios(){
$scenarios = parent::scenarios();
$scenarios['create'] = ['name', 'date'];
return $scenarios;
}
In controller:
$holiday = new HolidayHotels();
$holiday->scenario = 'create';
To know more about scenarios: http://www.yiiframework.com/doc-2.0/guide-structure-models.html#scenarios
You can add some condition based validation in your model rules. Here is the snippet for both client and server validation. You can many conditions inside the function block.
['field-1', 'required', 'when' => function ($model) {
return $model->check_box == '1';
}, 'whenClient' => "function (attribute, value) {
return $('#checkbox-id').is(':checked') ';
}"],
The easiest way to solve it is to send the model with empty strings. Then the controller checks if the strings are empty. If so, the model is not saved. Else, it is saved.
It was the only way that works for me.

Cakephp: generic validation rules in AppModel?

I'm wondering what's the "best" approach to validate fields generically. In my application several tables have date values that are always entered using a date picker widget. I don't want to repeat the validation code, so I would like to do something like filling the $validate array in the AppModel. But it gets overwritten in the concrete model class. The best I found so far is the paragraph "Dynamically change validation rules" in the cake book, and apply that logic to the AppModel somehow, but it looks a bit hacky and un-caky. Does anyone have a hint?
(If you have questions, please ask.)
Thanks
Just name them differently - unique so to speak:
public function validateDateTime() {}
etc. This way your custom rules don't verwrite the core rules and vica versa.
I had some validation rules that I wanted to put in 3 models, to not repeat the same code, here what I did
in AppModel.php, define some var with those rules that should be in multiple models.
public $validationRules = arra(
// rules here
);
and add them for necessary models in AppModel's constructor
public function __construct($id = false, $table = null, $ds = null) {
parent::__construct($id, $table, $ds);
/**
* add validation
*/
if (in_array($this->alias, array('MyModel1', 'MyModel2', 'MyModel3')) ) {
$this->validate = array_merge($this->validate, $this->validationRules);
}
}
if there are some custom validation functions, those can be moved to AppModel.php as well.

Resources