Laravel addOrUpdate() on basis of related table values? - php

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
]);

Related

How to properly update a model on laravel? Method Illuminate\Database\Eloquent\Collection::update does not exist

I made a page for a user to update his company information, all companies default values are null, when a user is created. When a user fills the information, i get this error:
Method Illuminate\Database\Eloquent\Collection::update does not exist
I am sure this error is because of my CompanyController#edit
public function edit(Request $request)
{
$this->validate($request, [
'company_name' => 'alpha|max:50',
'phone' => 'integer|max:50',
'gst_hst_number' => 'integer|max:50',
'country' => 'alpha|max:50',
]);
$companies = Company::where('id', Auth::user()->id)->get();
$companies->update([
'company_name' => $request->input('company_name'),
'phone' => $request->input('phone'),
'gst_hst_number' => $request->input('gst_hst_number'),
'country' => $request->input('country')
]);
return redirect()->route('company.index')->with('info', 'Company information was updated.');
}
I am stuck quite some time on this issue, would gladly apriciate help and information how to properly update my company models fillable fields.
‌As the error message says, you are using the update method on a collection, you have to change the select query to this:
$companies = Company::where('id', Auth::user()->id)->first();
Because the get() method returns a collection, not a single record.
Try this. ->get() is for multiple collections here you can directly update your records.
$companies = Company::where('id', Auth::user()->id)->update([
'company_name' => $request->input('company_name'),
'phone' => $request->input('phone'),
'gst_hst_number' => $request->input('gst_hst_number'),
'country' => $request->input('country')
]);;
Your using update method on collection, but collection doesn't have update method,
what you need is remove the get(), so you can use update method on eloquent builder:
$companies = Company::where('id', Auth::user()->id);
$companies->update([
'company_name' => $request->input('company_name'),
'phone' => $request->input('phone'),
'gst_hst_number' => $request->input('gst_hst_number'),
'country' => $request->input('country')
]);

How to insert into another table after Registration on Laravel?

So, I have a laravel web and have some tables, two of them are users and user_data.
user_data have a foreign key user_id that references to id on users.
users have general attributes like username, email, password, etc. and user_data have 1 on 1 relation with users and have attributes like game_money, game_job, game_tier, etc.
The columns are too long if I combine those 2 into 1 table, so I tought to normalize it.
User registration is working and running smooth. But I don't know how to add a new entry into user_data when a new user registered and add a new entry in users.
The attributes columns in user_data (like game_money,etc.) are filled by external application outside laravel, so all I need is to add an entry to user_data.user_id foreign key, and let the other attributes in user_data use the default values or null before being updated by the external apps.
Here is my user_data migration:
Schema::create('user_data', function (Blueprint $table) {
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users');
$table->string('account_tier')->default("Free");
$table->float('economy')->default(0);
$table->string('job')->nullable();
$table->timestamps();
});
Where should I put the insert query inside laravel? Or should I handle user_data using the external app?
Thank you very much.
You should use an id on user_data table as your primary key. By the way you can just use the following code for your desired result.
In the registration method use something like below:
$user = User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
]);
The user variable is holding the information of the newly created user. Now its time to insert into your user_data table. Assuming the model is UserData.
UserData::create([
'user_id' => $user->id,
............
]);
In RegisterController
inside create function
$user= User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
]);
//UserData is the Model of user_data table
$user->UserData->create(['job'=>$data['job']]);
return $user
Try To This Example:
use Illuminate\Support\Facades\DB;
$user_data= array(
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
);
$role_data= array(
'user_name' => $data['name'],
'email' => $data['email']
);
$response = DB::table('users')->insert($user_data);
$response = DB::table('role')->insert($role_data);
You can use the Model boot events as following when you define relationship each other these models;
public static function boot()
{
parent::boot();
self::created(function($model){
$model->userData()->create([
'user_id' => $model->id,
'job' => $model->job
]);
});
}

Laravel 5.5 unique validation rule on seperate table with different column name

So I have users and companies. A user belongs to one company.
I want to validate a user registration so that the business_name field they use to register is unique in the companies table, the goal is to not allow users from creating duplicate companies.
Here is my register function:
public function register(Request $request)
{
$validator = Validator::make($request->all(), [
'first_name' => 'required',
'last_name' => 'required',
'business_name' => 'required|unique:companies',
'email' => 'required|email|max:255|unique:users',
'password' => 'required|min:6',
]);
if ($validator->fails()) {
return response()->json(['error'=>$validator->messages()], 401);
}
}
The field I want to compare against is the companies.name to check for uniqueness.
Is this possible? At the moment it is trying to look for business_name in the companies table.
Never mind, managed to figure it out. Just needed an extra parameter to specify the column name:
'business_name' => 'required|unique:companies,name',

Laravel: Get the ID of User::create and insert new row using that ID

I have AuthController in Laravel and I have 2 tables, one is Users and one is Users_Information and I want to insert into Users_Information upon registration.
So I want to get the id from the following method and insert a new row and set the column ID of that row to the ID of the user I have just created.
/**
* Create a new user instance after a valid registration.
*
* #param array $data
* #return User
*/
protected function create(array $data)
{
return User::create([
'username' => $data['username'] . ' ' . $data['username2'],
'mail' => $data['mail'],
'password' => bcrypt($data['password']),
]);
}
I want to insert into Users_Information with a column id, current_food and current_level
I have a controller for the Users_Information called UserInformation, would I just call UserInformation::create but how would I get the id from the User::create?
Try to use ->id of returned object, something like:
$id = $this->create($data)->id;
The create() method returns the model.
$user = User::create([
'username' => $data['username'] . ' ' . $data['username2'],
'mail' => $data['mail'],
'password' => bcrypt($data['password']),
]);
$userInfo = UserInformation::create([
'user_id' => $user->id,
'current_food' => $food,
'current_level' => $level,
]);
Suppose, I have a model name Employee and I want to insert some data in this model also want to get table id. So I can achieve this easily by below code:
$employee = new Employee();
$employee->employeeName = 'Something';
$employee->save();
$employee->id;
Eloquent has a nice way to handle saving relationships, which can be used in your case. It allows you to save a related model without accessing the model directly. Of course you must make sure your relationship is defined in the appropriate models first.
Below will create the user and their information. I assumed the method of your relationship was called information but you can adjust as needed.
$user = User::create([
'username' => $data['username'] . ' ' . $data['username2'],
'mail' => $data['mail'],
'password' => bcrypt($data['password']),
])->information()->create([
'current_food' => $current_food,
'current_level' => $current_level
]);
Notice that we did not explicitly set user_id because we simply created the information by accessing the relationship you have defined; Laravel/Eloquent handles that for you!
use insertGetId(); it gives you the id of an inserted row.
$userId = User::insertGetId([
'name' => $request->input('name'),
'email' => $request->input('email'),
'password' => bcrypt($request->input('password')),
]);
https://laravel.com/docs/5.7/queries#inserts
Also, if you are not using Eloquent, you can use insertGetId:
$id = DB::table('users')->insertGetId(
[ 'name' => 'John Doe', 'email' => 'john#example.com']
);
Remember that if you set your table with an custom ID, you must indicate so in the code. In my case, my table "Antecedentes" has the custom id "ant_id" so "id" did not work and had to put "ant_id" like this:
$success = Antecedentes::create($data)->ant_id;
And i could go on.

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

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

Categories