Laravel DB table and eloquent method updateOrCreate - php

DB::table("mytable")->updateOrCreate([
'user_id' => $user_id,
'active' => 1,
'created_at' => Carbon::now()
]);
But this code return me error:
Call to undefined method
Illuminate\Database\Query\Builder::updateOrCreate()
So, according to this answer link (user stanb) I added:
protected $table = 'mytable';
And change code:
DB::table($this->table)->updateOrCreate([...
But still I have this same error

DB::table('table name')
->updateOrInsert(
['email' => 'admin#admin.com', 'name' => 'Admin'],
['id' => '7']
);
I disagree with the other answer, we can use query builder to insert or update.

It's Eloquent method, so you need to use model. Also, you need to pass two arrays as parameters:
Model::updateOrCreate([
'user_id' => $user_id
],
[
'active' => 1,
'created_at' => Carbon::now()
]);
In this example, if there is a record where user_id = $user_id, the record will be updated.

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

Can we pass a model to updateOrCreate method of eloquent Laravel?

Is there anyway to pass a model to updateOrCreate method of Eloquent laravel? My current code is working fine, in which i am passing array to updateOrCreate method.
$ud = UserDetail::updateOrCreate(
['user_id' => $user->id],
[
'father_name' => $request['fname'], 'dob' => $request['dob'],
'contact_no' => $request['contactNumber'], 'img_url' => $url,
'postal_address' => $request['postalAddress'],
'permanant_address' => $request['permanantAddress'],
'gender' => $request['gender'], 'religion' => $request['religion'],
'marital_status' => $request['maritalStatus'],
'district_id' => $request['district'], 'profile_status' => $status]);
I am using updateOrCreate method multiple times. So i want to create a model once, assign these values to the model, then pass it to updateOrCreate method instead of passing a large array.
//Create model and assign values
$user_d = new UserDetail;
$user_d->father_name = $request['fname'];
$user_d->dob = $request['dob'];
//pass the model to updateOrCreate method
$ud = UserDetail::updateOrCreate(
['user_id' => $user->id], $user_d );
You could use attributesToArray method
//Create model and assign values
$user_d = new UserDetail;
$user_d->father_name = $request['fname'];
$user_d->dob = $request['dob'];
$user_d->save();
//pass the model to updateOrCreate method
$ud = UserDetail::updateOrCreate([
'user_id' => $user->id
], $user_d->attributesToArray());

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 generate object using model factory with parameter

I have this model factory that generates new contact, it uses random company_id:
$factory->define(App\Models\Contact::class, function (Faker\Generator $faker)
{
$company_id = Company::all()->random()->id;
return [
'firstname' => $faker->firstName,
'lastname' => $faker->lastName,
'phone' => $faker->phoneNumber,
'email' => $faker->email,
'company_id' => $company_id,
'lead_id' => \App\Models\Lead::where('company_id', $company_id)->get()->random()->id,
];
});
It is ok when I use it in seeds:
factory(App\Models\Contact::class)->create();
But for testing I need somehow to pass $company_id to factory, create contact for concrete company_id (I know that I can do ->create(['company_id', $company_id])) but this will rewrite only company_id from Contact.
When I select lead_id, I also need to know current company_id.
How to pass company_id to factory as parameter?
Try to use this example:
$factory->define(App\Models\Contact::class, function ($faker, $params) {
$company_id = $params['company_id'];
....
});
and this to make a new object:
$newContact = factory(App\Models\Contact::class)->make(['company_id' => $current_company_id]);
Depends on your Laravel version it will be different.
For laravel 5.1
https://github.com/laravel/framework/issues/9245
You will need to check if is passed manually
// Testcase
$company = factory(App\Models\Company::class)->create();
factory(App\Models\Contact::class)->create(['company_id' => $company->id]);
// Factory
$factory->define(App\Models\Contact::class, function (Faker\Generator $faker, $attribues) {
// Manually check if id is passed
$company_id = (isset($attribues['company_id'])) ?: Company::all()->random()->id;
return [
'firstname' => $faker->firstName,
'lastname' => $faker->lastName,
'phone' => $faker->phoneNumber,
'email' => $faker->email,
'company_id' => $company_id,
'lead_id' => \App\Models\Lead::where('company_id', $company_id)->get()->random()->id,
];
});
For Laravel 5.2 and above you can simply pass id
https://laravel.com/docs/5.5/database-testing#relationships
// Testcase
$company = factory(App\Models\Company::class)->create();
factory(App\Models\Contact::class)->create(['company_id' => $company->id]);
// Factory
$factory->define(App\Models\Contact::class, function (Faker\Generator $faker, $attribues) {
// Manually check if id is passed
$company_id = (isset($attribues['company_id'])) ?: Company::all()->random()->id;
return [
'firstname' => $faker->firstName,
'lastname' => $faker->lastName,
'phone' => $faker->phoneNumber,
'email' => $faker->email,
'company_id' => function(){
return factory(\App\Models\Company::class)->create()
},
'lead_id' => \App\Models\Lead::where('company_id', $company_id)->get()->random()->id,
];
});
So, for your case, get your random company_id first and pass it to factory. Depends on your Larval version change the ContactModel factory. Or if you have relation that you can query, you can do it as well.
// If you have a relation
$contact = factory(App\Models\Contact::class)->create();
$company_id = $contact->company->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
]);

Categories