i want to edit my user email in laravel, but when i submit the form and then it gives me an error message
The selected Email is invalid.
what do I have to do?
whats wrong with this code?
//in Create Function
'email' => 'required|email|unique:users,email',
//in Update Function is this correct?
'email' => 'required|email|exists:users,email',
Controller
This is my userController for update users
public function update(Request $request, User $user)
{
$validator = Validator::make(
$request->all(),
[
'name' => 'required|string|max:30',
'email' => 'required|email|exists:users,email',
'role' => 'required',
'avatar' => 'required|string|max:150'
],
[],
$this->attributes()
);
if ($validator->fails()) {
$request['role'] = Role::select('id', 'name')->find($request->role);
return redirect()
->back()
->withInput($request->all())
->withErrors($validator);
}
DB::beginTransaction();
try {
$user->update([
'name' => $request->name,
'email' => $request->email,
'password' => Hash::make($request->password),
'avatar' => parse_url($request->avatar)['path'],
]);
$user->syncRoles($request->role);
Alert::toast(
__('posts.alert.delete.message.success'),
'success'
);
return redirect()->route('users.index');
} catch (\Throwable $th) {
DB::rollBack();
Alert::toast(
__('posts.alert.delete.message.error', ['error' => $th->getMessage()]),
'errors'
);
return redirect()
->back()
->withInput($request->all())
->withErrors($validator);
} finally {
DB::commit();
}
}
You still want a unique validator, so the user can't update their account to someone else's email address and cause a conflict.
However, to prevent it from failing when the user isn't updating their email address (it would fail the unique validation, because a record already exists with that email - the user's own), you'll want to exempt the user's current record from the validation.
https://laravel.com/docs/9.x/validation#rule-unique
See "Forcing A Unique Rule To Ignore A Given ID":
// at the top of your file
use Illuminate\Validation\Rule;
'email' => [
'required',
'email',
Rule::unique('users')->ignore($user->id),
]
You're validating the request requiring the email to exist in the table :
'email' => 'required|email|exists:users,email',
You need to specify unique in order to check the value is not used in the table (same as creation)
'email' => 'required|email|unique:users,email',
You can't do either
'email' => 'exists:users,email'
or
'email' => 'unique:users,email'
for update function. because if you don't change the email you have to submit the old email to the controller which is not "unique" and if you do change it then it doesn't "exist" in the database.
Instead try it like this:
'email' => ['required', 'email', Rule::unique('users', 'email')->ignore($user)],
It means the email should be unique unless it is the email from current user.
See the Laravel docs for more information on this:
https://laravel.com/docs/9.x/validation#rule-unique
Related
please I am trying to allow users to register with a coupon code, if coupon code is invalid dont register user, but when I tried it users are been registered even though the code is already used or invalid
I am using this package for the code https://github.com/michael-rubel/laravel-couponables
public function store(Request $request)
{
$request->validate([
'name' => ['required', 'string', 'max:255'],
'username' => ['required', 'string', 'max:255', 'unique:users'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'confirmed', Rules\Password::defaults()],
]);
$user = User::create([
'username' => $request->username,
'name' => $request->name,
'email' => $request->email,
'password' => Hash::make($request->password),
]);
$user->redeemCoupon($request->code);
event(new Registered($user));
Auth::login($user);
return redirect(RouteServiceProvider::HOME);
}
You are already registering the user before checking if the coupon is valid. Move this line after the validation.
$user->redeemCouponOr($request->code, function ($e) {
//handle the different exceptions here if not valid.
});
$user = User::create([
'username' => $request->username,
'name' => $request->name,
'email' => $request->email,
'password' => Hash::make($request->password),
]);
Or handle the validations inside the validator method
$request->validate([
...
'code' =>'sometimes|exists:coupon_table,coupon_code_column,coupon_status_column,!used_or_some_other_status'
]);
Make a custom validation rule to verify code and check if the code is already used.
$redeemer->verifyCoupon($code);
$redeemer->isCouponAlreadyUsed($code);
I don't see anything that is not explained in the Laravel Couponables package that you are using it clearly has explanations on the GitHub:
Listeners
If you go event-driven, you can handle package events:
CouponVerified
CouponRedeemed
CouponExpired
CouponIsOverLimit
CouponIsOverQuantity
NotAllowedToRedeem
FailedToRedeemCoupon
All the exceptions are well explained in the documentation
If something's going wrong, methods verifyCoupon and redeemCoupon will throw an exception:
CouponExpiredException // Coupon is expired (`expires_at` column).
InvalidCouponException // Coupon is not found in the database.
NotAllowedToRedeemException // Coupon is assigned to the specific model (`redeemer` morphs).
OverLimitException // Coupon is over the limit for the specific model (`limit` column).
OverQuantityException // Coupon is exhausted (`quantity` column).
CouponException
You can simply replace this line from your code:
$user->redeemCoupon($request->code);
To this:
$user->redeemCouponOr($request->code, function ($exception) {
// Your action with $exception!
print('This coupon is no longer valid'); //
});
I have a method that stores employee data on create however I have defined a default password to be randomly created and hashed. The password isn't stored for some reason.
Any ideas?
public function store(Request $request)
{
// get company
$company = Auth::user()->companies()->first();
// get and validate data
$storeData = $request->validate([
'firstname' => 'required',
'lastname' => 'required',
'email' => 'required|email',
'phone' => 'required|numeric|digits:11'
]);
// create employee with validated data
$employee = $company->employees()->create(array_merge($storeData), [
'password' => Hash::make(Str::random(40)),
]);
return redirect('/employees/' . $employee->id )
->with('success', 'Employee successfully created');
}
There's an typo in your code, try
$employee = $company->employees()->create(array_merge($storeData, [
'password' => Hash::make(Str::random(40)),
]));
The array_merge is closed too early and only contains what you have in the $storeData array.
I have a error, I'm using sanctum and I want to check that the email does not exist
the if returns an empty array but the if is satisfied because it returns true
$mail = $request->input(['email']);
if ($search = User::where('email', $mail)->get()) {
return response()->json(['msg' => 'account already exist'], 409);
} else {
$validate = $request->validate([
'name' => 'required|string|',
'email' => 'required|string',
'password' => 'required|string'
]);
}
any solution?
Why not use the Laravel validation since this looks more like validation, so something like:
$request->validate([
'name' => 'required|string|',
'email' => 'required|string|email|unique:users,email',
'password' => 'required|string'
]);
with this you don't need to do an if else. You can check the Laravel docs on https://laravel.com/docs/8.x/validation#introduction for more details
On my current project (a school management system) I want to give admins the ability to register users. Admins can create courses and subjects for example, which I've managed to do using resource controllers. However, I thought I could do the same for users, since the process appears the same to me. That is: I can show, edit, create, update and delete users.
However, I've run into several problems so far. Right now I can create users, but not update them.
Here's my code:
web.php
Route::middleware(['auth', 'admin'])->group(function () {
Route::get('/admin', 'HomeController#admin');
Route::post('register', 'UserController#store');
Route::resources([
'admin/cursos' => 'CursoController',
'admin/turmas' => 'TurmaController',
'admin/semestres' => 'SemestreController',
'admin/materias' => 'MateriaController',
'admin/usuarios' => 'UserController',
]);
});
UserController.php
public function update(Request $request, $id)
{
$rules = array(
'name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'role' => 'required|string',
'password' => 'required|string|min:6|confirmed',
);
$validator = validator::make(Input::all(), $rules);
if ($validator->fails()) {
// return dd();
return Redirect::to('/admin/usuarios/' . $id . '/edit')
->withErrors($validator);
} else {
// store
$user = User::find($id);
$user->name = Input::get('name');
$user->email = Input::get('email');
$user->role = Input::get('role');
$user->password = Input::get('password');
$user->save();
// redirect
Session::flash('message', 'Sucesso!');
return Redirect::to('/admin/usuarios');
}
}
Validation fails every time I try to update user information. What exactly is going on here? I'm relatively new to Laravel, so I'm a bit lost now.
If the request is failing when a user is trying to update their information without changing the email address, you need additional logic to ignore the id for user associated with the email.
Sometimes, you may wish to ignore a given ID during the unique check. For example, consider an "update profile" screen that includes the user's name, e-mail address, and location. Of course, you will want to verify that the e-mail address is unique. However, if the user only changes the name field and not the e-mail field, you do not want a validation error to be thrown because the user is already the owner of the e-mail address.
To instruct the validator to ignore the user's ID, we'll use the Rule class to fluently define the rule. In this example, we'll also specify the validation rules as an array instead of using the | character to delimit the rules:
Validator::make($data, [
'email' => [
'required',
Rule::unique('users')->ignore($user->id),
],
]);
Applied to your set of validation rules it would look like:
$rules = array(
'name' => 'required|string|max:255',
'email' => [
'required',
'string',
'email,
'max:255',
Rule::unique('users')->ignore(auth()->id())
],
'role' => 'required|string',
'password' => 'required|string|min:6|confirmed',
);
You have to except the User ID ($id) in email validation, since u use "unique" rule.
you can check the guide in here
https://laravel.com/docs/5.6/validation#rule-unique
While updating the "users" table, I want the EditUserRequest form checkout to ignore the current email because it already exists.
Code rules:
public function rules()
{
return [
'username' => 'required|max:200',
'email' => [
'required',
Rule::unique('users')->ignore($user->id),
],
'pass1' => 'required|min:6',
'pass2' => 'same:pass1',
];
}
Code UserController:
public function postEdit($id,EditUserRequest $request)
{
$user = User::find($id);
$user->name = $request->username;
$user->email = $request->email;
$user->password = Hash::make($request->pass1);
$user->level = $request->get('cbadmin',0);
$user->save();
return view('admin.edit-user')->with('success','Sửa thành công!');
}
This line: 'email' => 'required|email|unique:users,email' will check email exists. However, the default email I need to update it already exists. Did I read:https://laravel.com/docs/5.6/validation#rule-unique. But I do not understand how to solve this problem
public function rules()
{
return [
'username' => 'required|max:200',
'email' => 'required|email|unique:users,email,'.request()->user()->id,
'pass1' => 'required|min:6',
'pass2' => 'same:pass1',
];
}
You can pass a third parameter as id to ignore.
Hope this helps.
I am not sure of your route parameter names since your routes aren't included in the post, so I will assume $id on the controller method means there is a route parameter named id.
'email' => [
'required',
Rule::unique('users')->ignore($this->route('id')),
],
This would use the id from the route parameter, assuming it was named id. This will tell the rule to ignore the unique check on this email field for this particular User id.
you can do this by using the Rule facade ..
'email' => [
'required',
Rule::unique('users')->ignore($user->id),
],
EDIT
in case you're using a function to validate your inputs you may do it like this:
protected function yourValidatorName(array $data, $id)
{
return Validator::make($data, [
'username' => 'required|max:200',
'email' => [
'required',
Rule::unique('users')->ignore($id),
],
'pass1' => 'required|min:6',
'pass2' => 'same:pass1',
]);
}
then
public function postEdit($id, EditUserRequest $request)
{
$accountValidate = $this->yourValidatorName($request->all(), $id);
if (!$accountValidate->fails())
{
// success
}
else
{
// failed
}
}
Can you show me your route for postEdit?
For example this is your route:
Route::put('users/{user_id_sample}', 'UserController#postEdit');
You may do something like this:
public function rules()
{
return [
'username' => 'required|max:200',
'email' => [
'required',
Rule::unique('users')->ignore($this->route('user_id_sample')),
],
'pass1' => 'required|min:6',
'pass2' => 'same:pass1',
];
}