Validate field as unique with scope in cakephp - validation

I am creating a CakePHP application which have an edit form which contain one text box named air_id. In my table I am using project_id and air_id as composite primary key. So while updating air_id I need to validate uniqueness.
My table structure is like:
project_id air_id
1 test#test.com
1 test1#test.com
Currently I am using cakephp3.0 and I am using validateUnique rule with scope,
Following is my code:
$validator
->add('air_id', [
'unique' => [
'rule' => ['validateUnique', ['scope' => 'project_id']],
'provider' => 'table',
]
]);
And my controller is like this
$projectCustomers = $this->ProjectCustomers->newEntity($formData);
Now it is giving validation message every time. What I need is when I change the value test#test.com to test1#test.com it should raise the error and if I change it to some other value it should not raise the error. Is there something wrong in my validation?

CakePHP Unique Field Rules:
We have cakephp unique field rules that might be even better:
In your table(eg. UsersTable.php):
public function buildRules(RulesChecker $rules)
{
$rules->add($rules->isUnique(
['air_id', 'project_id'],
'Your validation error here.'
));
return $rules;
}
At the top of your table , don't forget to include this class:
use Cake\ORM\RulesChecker;
See Here (CakePHP Unique Fields Rules).

Related

Relationships in Laravel Backpack - Not sure I understand

I installed backpack on the latest version of Laravel 6.
Upon running this command as a test:
php artisan make:migration:schema create_posts_table --schema="user_id:unsignedInteger:foreign,
name:string, slug:string, description:text, keywords:string:nullable"
The command created a Post model in Models/Post
I would like to see the names of the users from the "user" table in my "post" CRUD.
First question:
I generate my CRUD with:
php artisan backpack:crud post
I see the CRUD, at the top of the CRUD I would like to pass the users name from the User table in the select dropdown.
I tried this:
protected function setupCreateOperation()
{
$this->crud->setValidation(PostRequest::class);
// TODO: remove setFromDb() and manually define Fields
//$this->crud->setFromDb();
$this->crud->setColumnDetails([
'label' => 'User', // Table column heading
'type' => 'select',
'name' => 'user_id', // the column that contains the ID of that connected entity;
'entity' => 'backpackuser', // the method that defines the relationship in your Model
'attribute' => 'name', // foreign key attribute that is shown to user
'model' => 'App\Models\backpackuser' // foreign key model
]);
}
But I am getting the error:
Symfony\Component\Debug\Exception\FatalThrowableError
Too few arguments to function Backpack\CRUD\app\Library\CrudPanel\CrudPanel::setColumnDetails(), 1
passed in C:\laragon\www\backpack\app\Http\Controllers\Admin\PostCrudController.php on line 41 and
exactly 2 expected
My problem "I think" is related to the "'entity' => 'backpackuser',"
From what I understand I need to add the relation method here but what I don't get is that Backpack did not create it when running the first command, is this normal?
Also, which model shall I user to pass the user details into a select field?
App/User or App/Models/BackpackUser ?
Thank you.
setColumnDetails() has two parameters:
the name/key of the column you're modifying
the attributes you're modifying and their new values
It looks like you've only provided the second parameter. Hence the error "Too few arguments to function setColumnDetails(), 1
passed and
exactly 2 expected."
Try:
$this->crud->setColumnDetails('user_id', [
'label' => 'User', // Table column heading
'type' => 'select',
'entity' => 'backpackuser', // the method that defines the relationship in your Model
'attribute' => 'name', // foreign key attribute that is shown to user
]);
Pro tip: you don't need to specify the model. If on your Post model you have the backpackuser() relationship properly defined, Backpack will pick up the model from that relationship.
Yes, you should create a relationship manually and add it to the Post model.
In this case (see Users in the Posts CRUD), you need to add relation method into Post, not User.

How to validate inputs from GET method? laravel

How can I validate my inputs from a GET method?
Example URL: localhost:8000?salary=2000&name=sample&description=vowewljfodigjfdglfd
In the URL I have 3 inputs and I want to validate:
Salary - should accept only numeric
Name - should accept only alphabetic
Description - should accept with max:1000
Somebody knows how to do this?
The Laravel validator doesn't care where the data came from. You can manually create a validator and pass it the query string data.
$validator = Validator::make($request->query(), [
'salary' => 'numeric',
'name' => 'alpha_num',
'description' => 'max:1000',
]);
if ($validator->fails()) {
// show an error
}
Side note: As someone with a hyphenated last name, I implore you not to treat name as alphanumeric. See Falsehoods Programmers Believe About Names.

Laravel - exclude current email from unique validation

I am trying to use unique on an email address in Laravel 5.5 validation like this..
$rules = [
'email' => 'email|unique:users,email,
];
This is working and is checking the 'users' table in the 'email' column
But if the email address is the same as the currently saved one then this also fails validation.
Is there a way I can add an exception rule to the validation to ignore $user-email?
The unique rule takes a third parameter: a record to ignore, see "Forcing A Unique Rule To Ignore A Given ID".
Pass in the ID of the record you do not wish to be included in the unique test, e.g:
$rules = [
'email' => 'email|unique:users,email,' . $user->id
];
THIS IS AN EASY SOLUTION
Just add $this->route('id') as the third parameter
if your route was defined like this:
Route::put('{company}', 'CompanyController#update')
->name('update');
then your parameter name is "company"
So in your FormRequest:
public function rules()
{
$rules = [
'url' => [
'required',
'url',
'unique:companies,url,'.$this->route('company') ?? 0
],
];
// dd($rules); << check yourself
return $rules;
}
This FormRequest works the same for insert or update.
this line will instruct to ignore "0" in case of insert
$this->route('company') ?? 0

CakePHP Validation nonBlank fails Whether the Field is Empty or !Empty

The docs say that 'notBlank' is a validation rule for fields that you want to make sure they are not empty, as in !empty($somevalue), but when I leave the field blank ('') or when I put a value in the field ('s0meCraZyPasSworD') it still display the error message?
Can anyone see what I'm doing wrong? The rest of the validations work like minlength, but I commented them out to get a better idea of why 'notBlank' doesn't appear to be working...
CONTROLLER:
// Set of validation rules to be run
$validateRules = [
'fieldList' => [
'currentpassword',
'newpassword',
'confirmpassword'
]
];
if ($this->Admin->validates( $validateRules )) {
...
}
MODEL:
class Admin extends AppModel
{
public $name = 'Admin';
public $validate = [
'currentpassword' => [
'notBlank' => [
'rule' => 'notBlank',
'message' => 'Current password is required.'
]
],
...
You tagged CakePHP 2.4 - notBlank was added in 2.7 so you have to use notEmpty or set allowEmpty to false...
The data sent to the model’s save() method must contain data for the
login field. If it doesn’t, validation will fail. The default value
for this key is boolean false.
required => true does not mean the same as the validation rule
notBlank(). required => true indicates that the array key must be
present - it does not mean it must have a value
From the official website:
http://book.cakephp.org/2.0/en/models/data-validation.html#required
So you will need another rule like the allowEmpty to validate this field and not the notBlank rule.

cakephp saveAssociated and validation foreign_key fails

I have two models that we're going to name Model and RelatedModel. Model has many RelatedModel. So if I add foreign key validation on validation array like:
public $validate = array(
'foreignKey' => array(
'rule' => 'numeric',
'required' => true,
'message' => 'The id of relatedmodel should be a number'
)
)
After I create a add() function to save new registers and in this function I use saveAssociated with validation true, this one fails throwing an error 'The id of relatedmodel should be a number'.
I'm debugging the code and saveAssociated checks validation of both models at the same time and before save Model.
Is this an issue?
I think what this function should do is to validate Model, save it, add foreignKey of RelatedModel and then validate it before save.
I came into this issue only recently. It's not an issue, saveAssociated() is designed to work this way unfortunately.
What you can do is alter the required => true on the fly using the model validator. Check out the book for more information.
http://book.cakephp.org/2.0/en/models/data-validation.html#dynamically-change-validation-rules
This is working as would be expected with your given rule. required in Cake means it expects the value of foreignKey to be set in the save data prior to saving. All the validation will happen before Cake saves the data (and therefore before foreignKey is generated).
You shouldn't need to validate that it is numeric if you are allowing Cake to generate this for you behind the scenes. If you want to check that it is being passed in the data for an UPDATE you could modify the required to be only for an update like this:-
public $validate = array(
'foreignKey' => array(
'rule' => 'numeric',
'required' => 'update',
'message' => 'The id of relatedmodel should be a number'
)
)
Personally I wouldn't bother validating foreign keys unless a user is setting them rather than Cake.
Update:
To validate the foreignKey if it exists in a form submission you can drop the required option from the validation rule:-
public $validate = array(
'foreignKey' => array(
'rule' => 'numeric',
'message' => 'The id of relatedmodel should be a number'
)
);
This will allow you to pass data where the foreignKey is not present without throwing a validation error whilst validating it if it is.

Resources