Validation check (if 1 equal to some value from database) Laravel 5 - php

Is there any way in Laravel 5 to check if some value equal with value from database?
Here is what I try to do: I have table users and in table users I have additional column admin_id. In validation I need to check if admin_id form database equal to 1.
Here is my current code:
$inputs = array(
'projects' => Input::get('project'),
'users' => Input::get('workers')
);
$rules = array(
'projects' => 'required',
'users' => 'required'
);
$validator = Validator::make($inputs,$rules);
if($validator->fails()){
return false;
}else{
return true;
}

I don't know what is users input here - is it if from users table? If yes, you can then create your rules this way:
$rules = array(
'projects' => 'required',
'users' => ['required', 'exists:users,id,admin_id,1']
);
So now it will be verified if users matches user_id from users table where admin_id equals 1.
You should also consider Laravel 5 Requests objects to validate input. It's much more clean than putting code in Controller/Model/Repository. More about Requst Validation.

$rules = array(
'projects' => 'required',
'users' => [
'required',
Rule::exists('users', 'id')->where(function ($query) {
$query->where('admin_id', 1);
}),
],
);
Or if the admin_id is dynamic, then use:
$variable = 1;
$rules = array(
'projects' => 'required',
'users' => [
'required',
Rule::exists('users', 'id')->where(function ($query) use ($variable) {
$query->where('admin_id', $variable);
}),
],
);

$rules = array(
'users' => 'exists:users,admin_id'
); where users table name. Can see you also wanna use users as form field name

Related

How to update a user only when value has not changed in the database and also avoid using other people's email

So, I have controller method which validates user and updates their information.
public function updateBasicInfo(Request $request)
{
$basic_info = Validator::make($request->all(), [
'fullname' => 'required|min:2|max:255',
'phone_number' => 'required|numeric|min:10',
'email' => 'required',
'country' => 'required',
'address' => 'required',
], [
'phone_number.min' => "The phone number must be at least 10 digits",
]);
if($basic_info->fails())
{
return response()->json([
'errors'=> $basic_info->errors()->all(),
]);
}
else
{
$basic_info = $basic_info->validated();
$user = request()->session()->get('id');
$currentUser = User::firstWhere('username', $user->username);
$currentUser->name = $basic_info['fullname'];
$currentUser->phone_number = $basic_info['phone_number'];
$currentUser->email = $basic_info['email'];
$currentUser->save();
UserDetail::firstWhere(['username' => $user->username])->update([
'address'=>$basic_info['address'],
'country' => $basic_info['country'],
]);
$current_user = $currentUser;
Mail::to($current_user->email)->send(new ProfileMail($user));
return response()->json(['success'=> 'Profile Updated Sucessfully']);
}
}
I want to update user but I don't want two users to have the same email and I also want the user email to change only if it's value has been changed in the database.
Check to make sure that only the user has that email in the whole table and update it to prevent double email records
Please, how do I do this?
I have tried calling the isDirty() method,nothing seems to work
You can use the unique validation rule for email with ignore to make sure that it doesn't receive an error if the new email is the same as the last email. (Unique validation only in comparison with other users). Check out this link.
$basic_info = Validator::make($request->all(), [
'fullname' => 'required|min:2|max:255',
'phone_number' => 'required|numeric|min:10',
'email' => 'required|unique:users,email,'.request()->session()->get('id'),
'country' => 'required',
'address' => 'required',
], [
'phone_number.min' => "The phone number must be at least 10 digits",
]);
The isDirty() method is to check if you set a value to any of the properties of instance. And it checks the change after it occured.isDirty()

How to make Custom Validation rule for unique Array dependent on other field laravel

I have working on Laravel 5.6. I have 4 dependent unique columns but don't know how to validate these dependent columns
here is my migration for unique constrain:
$table->unique(array('lvl4','document_type','nature_id','type_id'),'u_coa_lvl4_asn_dnt_uk');
lvl4 is array.
Thanks in advance
You can try manaully validating with something like this:
$data = [
'lvl4' => 'Level 4',
'document_type' => 'Some type',
'nature_id' => 1,
'type_id' => 7,
];
$validator = Validator::make($data, [
'data.lvl4' => [
'required',
Rule::unique('your_table')->where(function ($query) use($data) {
return $query->where('lvl4', $data['lvl4'])
->where('document_type', $data['document_type'])
->where('nature_id', $data['nature_id'])
->where('type_id', $data['type_id']);
}),
],
]);
if($validator->fails()) {
// it fails validation ...
}
This is untested, but something like this should work for you.
https://laravel.com/docs/5.6/validation#rule-unique

Unique two columns in laravel

I'm working with laravel 5.6 I have this table
users_groups table
with these columns user_id reference to users auto increment id and group_id reference to group auto increment id in groups table
Now I'm trying to validate the entry of data to be unique value for both columns together, but it can't be user_id and group_id the same in the table.
I found this code and tried it:
$validatedData = $request->validate([
'user_id' => 'required|unique_with:users_groups,group_id',
'group_id' => 'required|unique_with:users_groups,user_id',
]);
It gave me this error:
Method Illuminate\Validation\Validator::validateUniqueWith does not exist.
Any help please?
I believe what you're looking for is this:
// Haven't tried this code, but it should be pretty close to what you're looking for
use Illuminate\Validation\Rule;
$validatedData = $request->validate([
'user_id' => [
'required',
Rule::unique('users_groups')->where(function ($query) {
return $query->where('group_id', $request->group_id);
})
],
'group_id' => [
'required',
Rule::unique('users_groups')->where(function ($query) {
return $query->where('user_id', $request->user_id);
})
]
]);
The correct way to validate against a table in a database is to use unique:table name,column
for your case it should be
$validatedData = $request->validate([
'user_id' => 'required|unique:users_groups,group_id',
'group_id' => 'required|unique:users_groups,user_id',
]);
see laravel docs
you can use this
'user_id' => [
'required',
Rule::unique('users_groups')->where(function ($query) {
return $query->where('group_id', \request()->input('group_id'));
})
],
'group_id' => [
'required',
Rule::unique('users_groups')->where(function ($query) {
return $query->where('user_id', \request()->input('user_id'));
})
],
All of the above answers are correct and code can still be simplified
'user_id' => [
'required',
Rule::unique('users_groups')->where('group_id', request('group_id'))
],
'group_id' => [
'required',
Rule::unique('users_groups')->where('user_id', request('user_id'))
],

Laravel addOrUpdate() on basis of related table values?

Below is something I am trying to do:
I have users table and user_profiles table and I am inserting name, email in users table and phone, address, .... etc in user_profiles table.
I have to match each value to prevent duplication of user, I have found this laravel method addOrUpdate() but it works only for one table. But I have to match user_profiles values too i.e phone,address.
Below is example code
$result = $customer->updateOrCreate([
'name' => $request->name,
'city_id' => $request->city_id,
'area_id' => $request->area_id,
'email' => $request->email
], [
'name' => $request->name,
'city_id' => $request->city_id,
'area_id' => $request->area_id,
'email' => $request->email
]);
There any way to achieve this using Laravel techniques?
Regards
First make a relationship with user and user_profiles model like-
public function userProfile()
{
return $this->hasOne('App\Model\UserProfile','user_id','id');
}
And then in your post controller as you want to match each value to prevent duplication of user-
$result = User::where('name',$request->name)->where('email',$request->email)
->whereHas('userProfile', function($q) use ($request){
$q->where('city_id'$request->city_id)->where('area_id',$request->area_id)
)->first();
if(!$result){
////your registration here
}
If you want to check if a user with exactly the same data exists, you can't use updateOrCreate(). Do this instead:
$user = User::where('name', $request->name)->where('email', $request->email)->first();
$profile = $user->profile()->where('phone', $request->phone)->where('address', $request->address)->count();
if ($user && $profile) {
// User exists.
}
I would recommend using Laravel's Validator Facade. https://laravel.com/docs/5.4/validation#manually-creating-validators
This would check to make sure the name and email fields of the users and users_profile table are unique.
$validator = Validator::make($request->all(), [
'name' => 'required|unique:users|unique:users_profile',
'email' => 'required|unique:users|unique:users_profile',
]);
You could use updateOrCreate for both of your models for sake of uniqueness i assume email should be unique so first updateOrCreate() method will check if user exists for parameter $request->email then update if not then create and return user model instance (in both update/create case)
Second updateOrCreate() on UserProfile will check if there exist any data for user_id then update else add new row, I assume user_id will be a foreign key in user profile table
$user = User::updateOrCreate([
'email' => $request->email
], [
'name' => $request->name,
'email' => $request->email
]);
UserProfile::updateOrCreate([
'user_id' => $user->id
], [
'user_id' => $user->id,
'city_id' => $request->city_id,
'area_id' => $request->area_id
]);

Unique key violation upon edit

I am trying to update a blog post but I am getting unique key error from database part then I went without using model and directly accessing ORM but then again no success.
This is my routes spesific to edit
Route::get('/getedit/{slug}', array('as' => 'getedit', 'uses' => 'AdminController#getEdit'))->before('auth');
Route::post('/postedit', array('as' => 'postedit', 'uses' => 'AdminController#postEdit'))->before('auth');
Controller
public function getEdit($slug)
{
$article = Post::where('slug', '=' , $slug)
->firstOrFail();
return View::make('admin.edit', array(
'title' => $article->title,
'mainarticle' => $article->article,
'slug' => $article->slug,
'category' => $article->category
));
}
// Updates articles to database
public function postEdit()
{
$rules = [
'title' => 'required',
'article' => 'required',
'slug' => 'required|unique:posts,slug,9',
'category' => 'required'
];
$input = Input::all();
$validator = Validator::make($input, $rules);
if ($validator->fails()) {
return Redirect::route('getedit')
->withErrors($validator);
// withInput not defined
}
else
{
$slug = $input['slug'];
/*$affectedRows = Post::where('slug', '=', $slug)->update([
'title' => $input['title'],
'article' => $input['article'],
'slug' => $input['slug'],
'category' => $input['category']
]);*/
/*$affectedRows = Post::where('slug', '=', $slug)->firstOrFail();
$affectedRows->title = $input['title'];
$affectedRows->article = $input['article'];
$affectedRows->slug = $input['slug'];
$affectedRows->category = $input['category'];
$affectedRows->save();*/
$post = DB::table('posts')->where('slug', '=', $slug)->update([
'title' => $input['title'],
'article' => $input['article'],
'slug' => $input['slug'],
'category' => $input['category']
]);
if ($post) {
return Redirect::route('dashboard')
->with('flash_message','Article Successfully Inserted');
}
else
{
return Redirect::route('dashboard')
->with('flash_message','Error updating data');
}
}
}
My model is just creating object of database (I am accidentally following fat controller and thin model approach as I am just trying the framework).
I have tried using Post::find(1)->update($data); method but that is returning unique violation and my current approach is just executing else statement which is triggered upon update failure.
Note: I am new to Laravel and trying this for the first time.
When you update a post, you'd rather send a POST (or better PATCH/PUT- http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html) request to given resource.
That said, you would include edited row key in the url, and change your method to something like this:
// route
Route::post('/postedit/{id}', array('as' => 'postedit', 'uses' => 'AdminController#postEdit'))
->before('auth');
// controller
public function postEdit($id)
{
// if no posts with $id found, throws exception - catch it and eg. show 404
$post = Post::findOrFail($id);
$rules = [
'title' => 'required',
'article' => 'required',
'slug' => 'required|unique:posts,slug,'.$id, // to ignore this row in unique check
'category' => 'required'
];
// validate
$post->fill($input)->save(); // fill() in order to use mass-assignement check
// alternatively you can just update:
// $post->update($input);
// but then make sure $input has only elements corresponding to the table columns
Additionally, read about route grouping, so you don't need to add before('auth') to those routes separately.
You should check your database table indexes. You should make sure that only slug has unique index.
I see that you are checking unique for slug but you hardcoded 9 in the rule:
'slug' => 'required|unique:posts,slug,9',
It should be:
'slug' => 'required|unique:posts,slug,'.$id,
where $id id of post you try to edit.
You should include such id in your form as hidden element and not search records with slug that you have because it seems you can edit your slug and you may edit the wrong record or edit nothing.

Categories