Laravel/Ardent: SQLSTATE[HY093]: Invalid parameter number: mixed named and positional parameters - php

I'm trying to validate a User using Ardent's validate() method, but I always receive the HY093 error with the following extra information
(SQL: select count(*) as aggregate from:userswhereemail= my.email#gmail.com)
I used Sentry2 for my 'users' table database migration.
I have my User model set up like this:
/**
* Validation Rules for ARDENT here
*/
public static $rules = [
'first_name' => 'required',
'last_name' => 'required',
'email' => 'required|email|unique::users',
'password' => 'required|between:8,32|confirmed',
'password_confirmation' => 'required|between:8,32',
];
/**
* The attributes that can be added to a new User using $user->fill()
*
* #var array
*/
protected $fillable = [
'first_name',
'last_name',
'email',
'password',
'password_confirmation'
];
/**
* Automatically removes _confirmation attributes
*
* #var boolean
*/
public $autoPurgeRedundantAttributes = true;
From a form, I have POST data that includes ['email', 'first_name', 'last_name', 'password', 'password_confirmation] with their respective values that go to the following function in my UserController:
public function signup() {
// Create a new User object
$user = new User();
// Populate attributes with information described in User->fillable
$user->fill( Input::all() );
// Check if info is valid using Ardent's validate() method
if ( $user->validate() ) {
....
....
....
My code always fails on the if ( $user->validate() ) line. Can anyone help me shed some light upon this situation?

The issue was this line
'email' => 'required|email|unique::users'
Should have been
'email' => 'required|email|unique:users'
According to The Laravel Docs

Related

Laravel dynamic validation

I'm using Laravel and I have a custom validation. I want to pass some value to the validation class and validate it against the DB so I keep all the validation logic in the validation class. Here's my code but the validation error is not triggered:
public function rules() {
$userCode = UserCode::getCode();
$rules = [
'name' => 'required|string',
'email' => 'required|email',
$userCode => 'unique:user_codes,code,'. $userCode
];
return $rules;
}
What am I doing wrong here? the validation is never triggered even if the value $userCode already exists in the DB. The validation is triggered if the request contains bad email for example.
Edit: I have this user_codes table that has a code column that must be kept unique. UserCode::getCode() produces this code. So I also want to check if this code is unique or not in the table user_codes before passing it to the controller. I already have the custom validator but the problem is that I want it to also validate this code. The validator works fine with the other request body. The problem is that this code is not passed from the request body but it is simply generated from another method.
You could do this using a FormRequest class with the prepareForValidation() method. It should look something like this:
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class WhateverRequest extends FormRequest
{
protected function prepareForValidation(): void
{
$this->merge([
'user_code' => UserCode::getCode(),
]);
}
public function rules(): array
{
return [
'name' => 'required|string',
'email' => 'required|email',
'user_code' => 'unique:user_codes,code'
];
}
}
your question is not clear, I understand you have a column named by code
and you want to be unique, you can add usercode to request,
request()->merge(['userCode'=>$userCode]);
then
$rules = [
'name' => 'required|string',
'email' => 'required|email',
'userCode' => 'unique:user_codes,code,'.UserCode::getId().',id'
];
I answered what I understand from your question
Okay start with the following:
php artisan make:rule SomeAwesomeRule
Then edit that created Rule
class SomeAwesomeRule 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)
{
//some logic that needs to be handled...
}
/**
* Get the validation error message.
*
* #return string
*/
public function message()
{
return __('Some.nice.translated.message');
}
}
And then apply the rule
$rules = [
'name' => 'required|string',
'email' => 'required|email',
'userCode' => new SomeAwesomeRule(#this is a constructor so pass away)
];
see
$rules = [
'name' => 'required|string',
'email' => 'required|email',
'userCode' => 'unique:user_codes,code'
];
//or
$userCode="";
do{
$userCode = UserCode::getCode();
}
while(UserCode::where('code',$userCode)->first());
// after loop you sure the code is unique
$rules = [
'name' => 'required|string',
'email' => 'required|email',
];

Laravel not working method updateOrCreate

The user has a profile setting. I want if the user changes some fields to be updated. But I have a new column created and should be updated. Maybe someone is not doing it right. Help please. Thank you very much.
Controller
public function profile_settings_post(Request $request){
// Auth Specialist
$user = Auth::user();
// Data Specialist Validate
$data = $request->validate([
'first_name' => 'nullable|string',
'last_name' => 'nullable|string',
'phone_number' => 'nullable|integer',
'gender' => 'nullable',
'date_of_birth' => 'nullable',
'about_me' => 'nullable',
'address' => 'nullable',
'city' => 'nullable|string',
'country' => 'nullable|string',
'postal_code' => 'nullable|integer',
]);
$profile = $user->profile_settings()->updateOrCreate($data);
$profile->save();
// RETURN REDIRECT PROFILE SETTINGS INDEX
return redirect()->route('frontend.specialist.profile.settings');
}
User Model
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public static function countPercent($count, $maxCount){
//one percent
$one_percent = $maxCount / 100;
// $count how much is percent
$percent = $count / $one_percent;
return $percent;
}
// 1 User have 1 profile settings (ONE TO ONE)
public function profile_settings(){
return $this->hasOne(Profile_Settings::class);
}
}
Profile_Settings Model:
class Profile_Settings extends Model
{
// Fill in db
protected $fillable = [
'first_name', 'last_name', 'phone_number',
'gender', 'date_of_birth', 'about_me',
'address', 'city', 'country', 'postal_code',
];
// Profile settigns model belongs to User
public function user(){
return $this->belongsTo(User::class);
}
}
When I edit some kind of field. A new field is created in the database
profile settings database not working update create new columns
You probably didn't read carefully how works updateOrCreate
It performs update based on the condition that you're passing in and updates the fields, that you want, so you will have to pass 2 arrays.
Example from Laravel's webitse
// If there's a flight from Oakland to San Diego, set the price to $99.
// If no matching model exists, create one.
$flight = App\Flight::updateOrCreate(
['departure' => 'Oakland', 'destination' => 'San Diego'],
['price' => 99, 'discounted' => 1]
);
So this means we are updating all rows, where 'departure' = 'Oakland', 'destination' = 'San Diego' and setting price to 99$.
I your case you should decide the condition, when you should perform update query, it will be 1st array, and also decide which fields should be updated, put it in 2nd array.

Laravel 6: How to pass checkbox value into database user table upon registration

I have created a registration form using Laravel 6 default migration table and Auth register controller. Now I want to have two types of accounts, so I have a added a checkbox to the HTML form. If the checkbox is checked, the account should be of different type than when the checkbox in unchecked.
What I have:
Database tables:
account_types (id, name)
users (id, name, email, password, account_type_id)
HTML
<label class="switch">
<input id="register-toggle-switch" name="account-type" type="checkbox" autocomplete="off" checked onclick="toggleswitch()">
</label>
RegisterController.php
/**
* Get a validator for an incoming registration request.
*
* #param array $data
* #return \Illuminate\Contracts\Validation\Validator
*/
protected function validator(array $data)
{
return Validator::make($data, [
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'string', 'min:8', 'confirmed'],
// 'account_type_id' => ['required']
]);
}
/**
* Create a new user instance after a valid registration.
*
* #param array $data
* #return \App\User
*/
protected function create(array $data)
{
if (isset($_POST['account-type']))
{
$account = '1';
}
else if(!isset($_POST['account-type']))
{
$account = '2';
}
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
'account_type_id' => $account
]);
}
However this does not work as it returns an error saying:
"General error: 1364 Field 'account_type_id' doesn't have a default value" and then proceeds to show the attempted query which does not include the 'account_type_id' or its value at all.
So the question is:
Depending of the state of the checkbox in the form, how can I pass the respective id into the registration query ?
Laravel has mass-assignment protections on its models, which will send no value to the insert query, and thus cause the default value error. Make sure you tell the User model that it's OK to pass account_type_id via the $fillable variable.
On the User model:
protected $fillable = [
'name', 'email', ... 'account_type_id'
];

How to write a text into one database column for every new user during registration in Laravel 5.2?

I'm using Laravel 5.2 Auth feature and registration works fine.
Now I need to write a string in a special column in users table during registration. It's not a value from an HTML form input. It's a static text describing a user role (contributor). All users registering should receive a "contributor" value in user_role column.
I tried to achieve this by adding this line to AuthController.php:
'user_role' => 'contributor',
The whole function adding values to database looks like this:
/**
* Create a new user instance after a valid registration.
*
* #param array $data
* #return User
*/
protected function create(array $data)
{
return User::create([
'first_name' => $data['first_name'],
'last_name' => $data['last_name'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
'user_role' => 'contributor',
]);
}
When I try to register a new account, everything except 'user_role' => 'contributor', gets added.
What's the proper way to write "contributor" value for every new user into the user_role column?
Is it not working because that function only has the $data array set?
Did you add user_role to $fillable array on User model ?
If not you need to add it
Example
protected $fillable = ['name', 'email', 'password', 'user_role'];

Validation - Returning the first error for an AJAX response

I'm probably over complicating things where it's not needed, but I have a form that is submitted via AJAX and then validated. I'm trying to return the first error that occurs, but I can only ever seem to fetch validation.required which of course is useless to me; I can't tell the user which field failed and nor can I translate an appropriate error message.
What gives? How can I fetch a human-friendly error message and return it back as a JSON response?
Here's what I've got going so far... The biggest how-do-I is fetching the attribute name for the error message, but maybe there's a far easier way to manage this altogether...
/**
* Adds a new post to the system
*
* #param Request $request
* #return json
*/
public function store(Request $request)
{
// run validation
if(!empty($validator = $this->validate($request)))
{
return response()->json(trans('global/'.$validator->first(), ['attribute' => 'how to get attribute?!?!']), 400);
}
// some other logic...
}
/**
* Validates a post add or post update request
*
* #access private
* #param Request $request
* #return mixed
*/
private function validate(Request $request)
{
// set-up validation rules
$validator = Validator::make($request->all(), [
'username' => 'max:255|required',
'email' => 'email',
'service' => 'numeric|required',
]);
$validator->setAttributeNames([
'username' => "Username",
'service' => "Service",
]);
// run validation
if($validator->fails())
{
return $validator->errors();
}
return true;
}
Use code above in your controller store method and do not override validate method:
$rules = [
'username' => 'max:255|required',
'email' => 'email',
'service' => 'numeric|required',
];
$attributes = [
'username' => "Username",
'service' => "Service",
];
$this->validate($request, $rules, [], $attributes);
It will automatically returns errors json if validation fails.
Errors example:
{"username":["The Username field is required."],"service":["The Service field is required."]}

Categories