updating one attribute fails by validation laravel 4 - laravel

I have an Ardent (Laravel 4) model with validation rules as below:
public static $rules = array(
'title' => 'required|alpha_num|min:4',
'friendly' => 'required|alpha_num|url'
);
When I try this:
$page = Page::find($id);
$page->menu=1;
$page->save();
It fails, because of the validation rules of other fields. My question is how can I update only one field as above?

Force save without validation in Laravel
If you want to force save your model without validation, simply use the forceSave() method instead of save().
$model->forceSave()

Adding "sometimes" worked in my case. Equivalent code for you would be:
public static $rules = array(
'title' => 'sometimes|required|alpha_num|min:4',
'friendly' => 'sometimes|required|alpha_num|url'
);
See: http://laravel.com/docs/4.2/validation#conditionally-adding-rules

Related

FormRequest messages() function does not translate all rules [duplicate]

I'm working on a Laravel 5.8 project and trying to show custom validation messages for a validation which uses the requiredIf validation rule.
Here is how I have it set up:
$validation = Validator::make(
$request->all(),
[
...
'sum' => [
Rule::requiredIf(function() use ($request){
$model = Model::find($request->id);
return $model->is_special; //returns a boolean value
}),
'numeric'
],
...
],
[
...
'sum.required_if' => 'This cannot be blank',
'sum.numeric' => 'Must use a number here',
...
]
);
Now the validation is working correctly and the custom message for the numeric validation shows as should, but the message I get for the requiredIf() method is Laravel's default error message.
I also tried using 'sum.requiredIf' => '...' but that didn't work either and can't seem to find any documentation or example for this scenario.
I was tinkering with this for a while and noticed that for this to work I needed to define
'sum.required' => 'This cannot be blank'
and not 'sum.required_if' => 'This cannot be blank',.
Not sure if this is expected behavior or just a workaround but my deduction is that with the callback Rule::requiredIf(function() use ($request){...}) the parameters :other and :value are not passed so it falls back onto required messaging and I guess this makes sense since required_if and required would not be used on the same :attribute.
Hope this helps anyone who comes across this problem.
First, create a rule name isSpecial or whatever
php artisan make:rule isSpecial
Go to App\Rules\isSpecial.php
private $id;
public function __construct($id) // pass id or what you need
{
//
$this->id=$id;
}
public function passes($attribute, $value) // customize your rules here
{
//
return Model::find($request->id)->is_special;
}
public function message() // here is answer for your question
{
return 'The validation error message.'; // your message
}
in your controller
use App\Rules\isSpecial;
\Validator::make($request->all(), [
'sum' => new isSpecial() ,
])->validate();
another idea :
Specifying Custom Messages In Language Files
In most cases, you will probably specify your custom messages in a language file instead of passing them directly to the Validator. To do so, add your messages to custom array in the resources/lang/xx/validation.php language file.
'custom' => [
'email' => [
'required' => 'We need to know your e-mail address!',
],
],
Simple notice:
- I suggest using HTTP Requests instead use validation in your controller and function direct
Looks like as of Laravel 8, using required_if works as expected, and alternatively will not fall back on required as mentioned previously:
'sum.required_if' => 'This cannot be blank',

Laravel Active Validation Rule

I am extremely new to Laravel and I was wondering if you could help me create a Custom Validation Rule, I am using version 5.5 of Laravel.
What I try to do is the following, I understand that the validations can be defined in the following way:
'email' => 'required|string'
I would like to add a new rule, in specific one called 'active'
In the application that I want to create I have several tables in which there are columns called 'active' (boolean) .. example
Users:
id|name|email|active
Roles:
id|name|active
I need a rule that I can call as follows:
'email' => 'required|string|active'
In short, I need a rule that verifies in a specific table, if the value I'm validating is active, and if not, send me a message. Thank you very much in advance
Try to use the Rule class and 'exists' validation:
use Illuminate\Validation\Rule;
'email' => [
'required',
'string',
Rule::exists('your_table')->where(function ($query) {
$query->where('active', 1);
}),
]

Validating fields based on old values in eloquent

Is there a way to validate model based on eloquent models old values?
For example I do not want to be able to save field status to PUBLISHED directly from DRAFT status. It has to be APPROVED to go to PUBLISHED status.
For example, I can validate a model with these rules:
private $rules = array(
'color' => 'required|alpha|min:3',
'status' => 'required',
// .. more rules here ..
);
So whenever I try to fill status with null value , validation will not pass.
What I need is also to not allow to change status from value 1 to 3, something like
private $rules = array(
'color' => 'required|alpha|min:3',
'status' => 'required|cant_be_changed_from_1_to_3_directly',
// .. more rules here ..
);

Using a php variable for validation in Laravel 4.2

I have this code that gets an object in a session and i put it in a certain variable. Then i wanted to use it in the laravel 4.2 'same' validation. So far here is the code i have
session_start();
$getsCapt = $_SESSION["captcha"];
$rules = array(
'st' => 'required',
'capt' => 'required|numeric|same:$getsCapt'
);
It is not doing anything. What i wanted to have is i'll compare the value i get from the session with the value i get from the textbox in my view named 'capt' but so far its not doing anything. any ideas to do this properly?
First of all, You are using same validator incorrectly.
same expects a form field name
Example:
same:field_name
Where, the given field must match the field under validation.
You could register and use a Custom Validation Rule
Validator::extend('captcha', function($attribute, $value, $parameters)
{
$captcha = \Session::get('captcha');
return $value == $captcha;
});
So later you can do:
//session_start(); - Please no need for this in Laravel
//$getsCapt = $_SESSION["captcha"]; - Also remove this not necessary
$rules = array(
'st' => 'required',
'capt' => 'required|numeric|captcha'
);
NB:
Use Session::put to save something to session e.g \Session::put('something');
There is also Session::get for retrieving value from session e.g \Session::get('something');
Please avoid using $_SESSION not Laravel way of doing things
[Edited] Where to Register Custom Validation Rule?
There are basically two ways you can register a custom validation rule in Laravel.
1. Resolving from a closure:
If you are resolving through closure you can add it to : app/start/global.php
Validator::extend('captcha', function($attribute, $value, $parameters)
{
$captcha = \Session::get('captcha');
return $value == $captcha;
});
2. Resolving from a class
This is the best and preferred way of extending custom validation rule as its more organised and easier to maintain.
i. Create your own validation class, CustomValidator.php, maybe in app/validation folder
<?php namespace App\Validation;
use Illuminate\Validation\Validator;
use Session;
class CustomValidator extends Validator{
public function validateCaptcha($attribute, $value, $parameters)
{
$captcha = Session::get('captcha');
return $value == $captcha;
}
}
NB: Notice the prefix validate used in the method name, validateCaptcha
ii. Create a Service Provider that will resolve custom validator extension in app/validation folder
<?php namespace App\Validation;
use Illuminate\Support\ServiceProvider;
class CustomValidationServiceProvider extends ServiceProvider {
public function register(){}
public function boot()
{
$this->app->validator->resolver(function($translator, $data, $rules, $messages){
return new CustomValidator($translator, $data, $rules, $messages);
});
}
}
iii. Then add CustomValidationServiceProvider under app/config/app.php providers array:
'providers' => array(
<!-- ... -->
'App\Validation\CustomValidationServiceProvider'
),
iv. And add the custom error message in app/lang/en/validation.php
return array(
...
"captcha" => "Invalid :attribute entered.",
...
)
Change single quotes to double quotes
$rules = array(
'st' => 'required',
'capt' => "required|numeric|same:$getsCapt"
);
Or simply concatenate the value
$rules = array(
'st' => 'required',
'capt' => 'required|numeric|same:' . $getsCapt
);

Yii2 : Active Record Column Aliases

I'm using Yii2 framework with advanced template.
I get problem with column alias in my controller file, here's my code:
$models = new ActiveDataProvider([
'query' => User::find()->select(['member'=>'fullname'])
]);
The above query equivalent with:
SELECT fullname AS member FROM User;
I send the data to the view using this code:
return $this->render('view', [
'model' => $models,
]);
I want to call the data in my view using GridView widget, here's my code:
echo GridView::widget([
'dataProvider' => $model,
'columns' => [
'member',
],
]);
However, I got an error that tell me the 'member' parameter is not defined.
How can I show the data of my query by calling the column name? (in my case it using alias)
I really appreciate any kind of helps!!
You should simply declare this attribute in your model :
class User extends ActiveRecord
{
public $member;
Read more : https://www.yiiframework.com/doc/guide/2.0/en/db-active-record#selecting-extra-fields
ActiveDataProvider works only with model attributes. member obviously is not presented there.
First of all, maybe it's better to refactor column names to be more clear instead of writing aliases? I don't see any benefit in your example.
If you nevertheless need to use aliases, as alternative for adding additional properties to class, you can work with them with help of ArrayDataProvider and SqlDataProvider.
Examples of usage:
ArrayDataProvider:
use yii\data\ArrayDataProvider;
$dataProvider = new ArrayDataProvider([
'allModels' => User::find()->select(['member' => 'fullname'])->all(),
]);
SqlDataProvider:
use yii\data\SqlDataProvider;
use yii\db\Query;
...
$query = (new Query())
->select(['member' => 'fullname'])
->from('users');
$command = $query->createCommand();
$dataProvider = new SqlDataProvider([
'sql' => $command->sql,
'params' => $command->params,
'totalCount' => $query->count(),
]);
For more details and features of usage please see official docs.
For your case it's better to use ArrayDataProvider, SqlDataProvider is for more complex queries.
In case of one alias and using model methods adding additional attribute as suggested by soju can be better.
But in my opinion it's useless and it's better to refactor column names in case of some ambiguity.

Resources