Hi @stevebauman, I would like to implement Rule::unique('table')->ignore($model) in LDAP way in case for update user data.
So far I check in Laravel documentation that unique and ignore only available in Database: https://laravel.com/docs/8.x/validation#rule-unique. Do you have any idea about this case? So far, I make custom validation rule for unique username. It works when store data but it doesn't passed when update the data.
<?php
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
use App\Ldap\User;
class LdapUsernameExist implements Rule
{
/**
* Create a new rule instance.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Determine if the validation rule passes.
*
* @param string $attribute
* @param mixed $value
* @return bool
*/
public function passes($attribute, $value)
{
$user = User::where('uid', '=', $value)->first();
return empty($user) ? true : false;
}
/**
* Get the validation error message.
*
* @return string
*/
public function message()
{
return 'Username sudah digunakan oleh pengguna lain.';
}
}
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use App\Rules\LdapUsernameExist;
class UpdateUserRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
// return false;
}
public function messages()
{
return [
'unud_user_type_id.required' => 'Tipe pengguna wajib diisi',
'name.required' => 'Nama wajib diisi',
'email.required' => 'Email wajib diisi',
'identifier.required' => 'ID pengenal wajib diisi',
'username.required' => 'Username wajib diisi'
];
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'unud_user_type_id' => 'required',
'name' => 'required',
'email' => 'required',
'identifier' => 'required',
'username' => ['required', 'max:50', 'min:3', new LdapUsernameExist] // expect the username is unique but ignored if it doesn't update.
];
}
}
Hi @stevebauman, could you please follow up this issue? Thank you.
Hey @satyakresna!
This should work for you:
<?php
namespace App\Rules;
use App\Ldap\User;
use LdapRecord\Models\Model;
use Illuminate\Contracts\Validation\Rule;
class UniqueLdapUser implements Rule
{
/**
* The model being ignored from validation.
*
* @var null|Model
*/
protected $ignore;
/**
* Determine if the validation rule passes.
*
* @param string $attribute
* @param string $value
*
* @return bool
*/
public function passes($attribute, $value)
{
$user = User::where('uid', '=', $value)->first();
if (is_null($user)) {
return true;
}
if ($this->ignore) {
return $this->ignore->is($user);
}
return false;
}
/**
* Ignore the LDAP model from being validated.
*
* @param null|Model $model
*
* @return $this
*/
public function ignore(Model $model = null)
{
$this->ignore = $model;
return $this;
}
/**
* Get the validation error message.
*
* @return string
*/
public function message()
{
return 'A user with this :attribute already exists.';
}
}
Then, inside your FormRequest:
Note: I'm assuming you're using model binding, as we discussed in a previous issue, so your users model instance should be available in the
FormRequestvia theldap-userproperty (i.e.$request->get('ldap-user')).
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use App\Rules\UniqueLdapUser;
class UpdateUserRequest extends FormRequest
{
public function messages()
{
return [
'unud_user_type_id.required' => 'Tipe pengguna wajib diisi',
'name.required' => 'Nama wajib diisi',
'email.required' => 'Email wajib diisi',
'identifier.required' => 'ID pengenal wajib diisi',
'username.required' => 'Username wajib diisi'
];
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'unud_user_type_id' => 'required',
'name' => 'required',
'email' => 'required',
'identifier' => 'required',
'username' => ['required', 'max:50', 'min:3', (new UniqueLdapUser)->ignore($this->get('ldap-user'))],
];
}
}
Let me know if you run into any difficulties or issues 馃憤
Hi @stevebauman, sorry the code doesn't work. It doesn't ignore the unique user.
I'm curious is that the get() method from $this->get('ldap-user') comes from FromRequest class? Then, where's the is() method in $this->ignore->is($user) comes from?
Oh, I understand. The is() method comes from LdapRecord Model and get() method comes from FormRequest by Laravel it self. But, it seems odd when I dd($user) in ignore method doesn't work.
I suspect that the get() method in ignore($this->get('user')) doens't catch the Ldap Model.
Notes: The 'user' is my route binding that I has set in RouteServiceProvider.
/**
* Ignore the LDAP model from being validated.
*
* @param null|Model $model
*
* @return $this
*/
public function ignore(Model $model = null)
{
dd($model); // result null
$this->ignore = $model;
return $this;
}
Could you please help about this case?
Hi @satyakresna,
The return value of $this->get('ldap-user') should be a App\Ldap\User instance -- if you've setup model binding for the ldap-user parameter.
If it's returning null, try using $this->route('ldap-user').
Instead of trial and error, I would simply try dumping the entire request object using dd() and inspecting it to see if your App\Ldap\User instance is available in the requests data.
If it's returning
null, try using$this->route('ldap-user').
Hi @stevebauman, It works great with $this->route('ldap-user') instead of $this->get('ldap-user'). Thanks a lot Steve. Really appreciate.
Awesome @satyakresna! Happy to help. Really glad you're up and running 馃帀