This is very good job I wanted to use it on my Rad4PHP CRUD (www.rad4php.com) scaffolding generator, while testing the usage I come across problem in validation when updating and checking for unique validation attribute it errors to field value already taken (it does not exclude the current record from this check): e.g $validator=Validator::make(Input::all(),array(
'username' =>'required|unique:users,username,'.$id,
'email' =>'required|unique:users,email,'.$id,
'password' =>'required',
'repassword' =>'required|same:password'
));
I do not have this problem on MySql only MongoDB, Any advise and suggestion to resolve it highly appreciated
I have sorted this problem as follows:
(please note this workaround is ok for MongoDB only)
edit (laravel bas folder)/vendor/laravel/framework/src/illuminate/Validation/Validator.php
change at line 1009 9 (just add _ to the id):
$idColumn = isset($parameters[3]) ? $parameters[3] : 'id';
to
$idColumn = isset($parameters[3]) ? $parameters[3] : '_id';
Since mongodb uses _id for id field and not id as in MySql and other databases.
I have tested this and works perfect with my Rad4PHP CRUD generator (www.rad4php.com)
Its never a good practice to edit the vendor source.
You could simply make your model use primary key as id.
protected $primaryKey = '_id';
You are absolutely right  but unfortunately there is no way around this problem but to modify the source code, I have tried your suggestion but did not work (still does not exclude the current record from checking unique rule).
So it is up to jessegers to sort this problem, meanwhile my workaround is fine as long as you are using Mongodb.
Thanks M A Shalash M.Sc. B.Sc.
Â
On Thursday, 15 January 2015, 22:48, Ahsen M <[email protected]> wrote:
Its never a good practice to edit the vendor source.
You could simply make your model use primary key as id.
protected $primaryKey = '_id';—
Reply to this email directly or view it on GitHub.
Inside Model
public static function rules ($id=0, $merge=[]) {
return array_merge(
[
'username' => 'required|min:3|max:12|unique:users,username' . ($id ? ",$id" : ''),
'email' => 'required|email|unique:member'. ($id ? ",id,$id" : ''),
'firstname' => 'required|min:2',
'lastname' => 'required|min:2',
],
$merge);
}
Validation on create:
$validator = Validator::make($input, User::rules());
Validation on update:
$validator = Validator::make($input, User::rules($id));
Validation on update, with some additional rules:
$extend_rules = [
'password' => 'required|min:6|same:password_again',
'password_again' => 'required'
];
$validator = Validator::make($input, User::rules($id, $extend_rules));
Giving me an error
MongoResultException (15959)
localhost:27017: exception: the match filter must be an expression in an object
/var/www/html/fitadmin/vendor/jenssegers/mongodb/src/Jenssegers/Mongodb/Collection.php
{
$query[] = '{...}';
}
}
$start = microtime(true);
$result = call_user_func_array(array($this->collection, $method), $parameters);
// Once we have run the query we will calculate the time that it took to run and
edit (laravel bas folder)/vendor/laravel/framework/src/illuminate/Validation/Validator.php
change at line 1009 9 (just add _ to the id):
$idColumn = isset($parameters[3]) ? $parameters[3] : 'id';
to
$idColumn = isset($parameters[3]) ? $parameters[3] : '_id';
but does not work
Hi SanJay1688
According to Laravel docs,I use rules as follows:
protected $rules =array(
'username' => 'required|unique:users,username,{id}',
);
Use my generater at (www.rad4php.com) current version it will generate CRUD scaffolding and all the models, views, routes ...
If you wait a week I will upload a new version with graphical interface.
Thanks
i like how L5 handle validations, You have different class which extends formRequest. Maybe take a look at that. Cleaner and effective code.
After digging into the source code a bit you will find this:
/vendor/laravel/framework/src/Illuminate/Validation/Validator.php
/**
* Get the excluded ID column and value for the unique rule.
*
* @param array $parameters
* @return array
*/
protected function getUniqueIds($parameters)
{
$idColumn = isset($parameters[3]) ? $parameters[3] : 'id';
return [$idColumn, $parameters[2]];
}
It's looking for a 3rd parameter to define the id field.
Simply put: your rule should look like this: 'email' => 'required|email|unique:users,email,'.$id.',_id',
Thats:
'{field}' => '{rules}:{targetTable/Collection},{targetColumn},{exclusionRecord/ID},{exclusionColumn}',
I bet this is somewhere in the documentation but why the hell use the short way of finding information?
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
Most helpful comment
After digging into the source code a bit you will find this:
/vendor/laravel/framework/src/Illuminate/Validation/Validator.phpIt's looking for a 3rd parameter to define the
idfield.Simply put: your rule should look like this:
'email' => 'required|email|unique:users,email,'.$id.',_id',Thats:
'{field}' => '{rules}:{targetTable/Collection},{targetColumn},{exclusionRecord/ID},{exclusionColumn}',I bet this is somewhere in the documentation but why the hell use the short way of finding information?