Save if new many to many relationships Laravel Eloquent - laravel

I have two models : Event and Soundcloud.
Both are defined to be a many-to-many relationship in Laravel and it is working fine.
I am saving the soundcloud and population the pivot table event_soundcloud by doing this
foreach ($data as $artist => $url) {
$soundcloud = Soundcloud::firstOrNew(['artist_name' => $artist, 'link' => $url]);
$event->soundclouds()->save($soundcloud);
}
That function is called every 10 minutes and each time the same records are added to the pivot table.
Is there a way to do the same thing but adding records in pivot table only if it does not exist already ?
Thank you

Here is what I did to make it work. I guess you cannot do it in one step
$soundcloud = Soundcloud::firstOrNew(['artist_name' => $artist, 'link' => $url]);
$soundcloud->save();
$event->soundclouds()->sync([$soundcloud->id], false);

Related

Loading relation of new model in Laravel

I just want to get hasOne relation of New model.
Can I load it before I will save it.
I have $user = new User(['order_id' => $order_id]);
How can I get $user->order; without build new request?
As others have already pointed out the model must be saved before retrieving any relations.
My usual approach for this is using lazy eager loading:
// Create new model with data
$newModel = Model::create([
'column' => $value
]);
// Use load to retrieve any relations
return $newModel->load('myRelationship');

Laravel 8.0 facing issue while trying to update a table with vue form, 'Attempt to read property \"item_id\" on null'

So, i have a table called Items table and another table called item_quantities, on item_quantities ive a column named item_id which is connected to items table id. All the fillable properties on both tables are all in one form on the frontend, and i take care of the form fields on the backend
Whenever i try to update the quantity on the form which is from item_quantities's table with a form, i'm facing serious issue updating the item_quantities. getting Attempt to read property "item_id" on null.
It all started when i noticed a duplicate entries on the item-quantities table, so i deleted all the datas on it..
Here's is the form screenshot
The vue form
and the backend logic
public function saveData(Request $request, $id) {
// dd($request->name);
$updateGroceries = Item::where('id', $request->id)->get()->first();
$updateGroceries->update([
'name' => $request->name,
'description' => $request->description,
'price' => $request->price,
]);
if($updateGroceries) {
$item_quantity = ItemQuantity::where('item_id', $updateGroceries->id) ?
ItemQuantity::where('item_id', $updateGroceries->id)->get()->first() :
new ItemQuantity;
if($item_quantity->item_id == null) {
$item_quantity->item_id = $updateGroceries->id;
}
$item_quantity->quantity = $request->quantity;
$item_quantity->save();
}
}
I'M SO SORRY IF MY ENGLISH WAS'NT CLEARED ENOUGH
Thanks in anticipation
You can simply use firstOrNew() method. This will first find the item, if not exist create e new instance.
$item_quantity = ItemQuantity::firstOrNew(['item_id' => $updateGroceries->id]);
$item_quantity->quantity = $request->quantity;
$item_quantity->save();
Note that the model returned by firstOrNew() has not yet been persisted to the database. You will need to manually call the save method to persist it.
Actually your errors workflow as that:
$item_quantity=null;
$item_quantity->item_id;
You can do that with optional global helper:
optional($item_quantity)->item_id ?: 'default value';

OctoberCMS belongsTo relationship saving problem

I have two models:
Brands
Mods
I can display all brands via belongsTo function. Problem is when I try to save same brand two times, I get error duplicated entry.
This belongsTo is causing duplicated entry error when saving to DB two same brands.
Mods.php
public $belongsTo = [
'brand' => [\Slasher\Farming\Models\Brands::class, 'key' => 'id'],
];
This belongsToMany works, and save's data to DB, but is generating checkbox field (I only want to select one brand at one mod enty). I'm using pivot table for this relation.
Mods.php
public $belongsToMany =[
'brand' =>[
'Slasher\Farming\Models\Brands',
'table' => 'slasher_farming_mods_brands',
'order' => 'brand_name'
],
];
BelongsTo example: (Brands are visible and I can save them. But problem is when saving same brand for more than two times).
Error I get when saving with belongsTo.
I tried also creating inverse relationships on Brands model with (belongsTo and belongsToMany), but still getting this error.
What type of relation should I make, to save Brands as dropdown list and to fix this duplicate error?
If you're using a pivot table for your relation, then you should use $belongsToMany. Pivot table is only used for many-to-many relations.
I fixed this problem with changing column in the mods name brand to brand_id and also changing belongsTo relation. I just removed key, and it works like a charm. No need for pivot table here.
Mods.php
public $belongsTo = [
'brand' => ['Slasher\Farming\Models\Brands']
];
"SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '3' for key 'PRIMARY' (SQL: update liam_blog_blogs set id = 3, liam_blog_blogs.updated_at = 2022-07-26 09:30:09 where id = 2)"

Laravel 5.5 - update or create bulk insert

i am trying to preform update or create action on many records using laravel model.
Normal insert with updateOrCreate works perfectly with foreach but i want to avoide it as it slowing things down.
I have something like 200k records.
Is there is any way to achive it?
I tried this answer below
https://stackoverflow.com/a/34815725/1239122
But it is not super elegant.
Any ideas?
You can try this library for batch insert and update.
https://github.com/mavinoo/laravelBatch
I didn't find a way to bulk insert or update in one query. But I have managed with only 3 queries. I have one table name shipping_costs. Here I want to update the shipping cost against the shipping area. I have only 5 columns in this table id, area_id, cost, created_at, updated_at.
// first get ids from table
$exist_ids = DB::table('shipping_costs')->pluck('area_id')->toArray();
// get requested ids
$requested_ids = $request->get('area_ids');
// get updatable ids
$updatable_ids = array_values(array_intersect($exist_ids, $requested_ids));
// get insertable ids
$insertable_ids = array_values(array_diff($requested_ids, $exist_ids));
// prepare data for insert
$data = collect();
foreach ($insertable_ids as $id) {
$data->push([
'area_id' => $id,
'cost' => $request->get('cost'),
'created_at' => now(),
'updated_at' => now()
]);
}
DB::table('shipping_costs')->insert($data->toArray());
// prepare for update
DB::table('shipping_costs')
->whereIn('area_id', $updatable_ids)
->update([
'cost' => $request->get('cost'),
'updated_at' => now()
]);
You can use insert() in Query Builder to bulk insert. But update statement needs conditions. Please read the document:
https://laravel.com/docs/5.7/eloquent#updates
As far as I know, you can not do it for the update as you need to check the condition for the update, But you can do it for insert
$data = array(
array('name'=>'John', 'phone'=>'1234567890'),
array('name'=>'Deo', 'phone'=>'9876543210'),
//...
);
Model::insert($data);

Laravel Factory Can't Save Relation

I use Laravel 5.6, and I have a problem with my seeder.
I use this :
factory(\App\Models\Merchant::class)->create([
'email' => 'admin#domain.com',
])->each(function ($m) {
$m->stores()->save(factory(\App\Models\Store::class)->create()
->each(function ($s) {
$s->products()->save(factory(\App\Models\Product::class, 10)->create());
})
);
});
All are hasMany relations.
Doing this, I have this error :
General error: 1364 Field 'merchant_id' doesn't have a default value
(SQL: insert into stores ....)
It's like my first $stores->save( ... ) doesn't use the merchant created.
In my DB, I have one merchant created.
If I use ->make() instead of ->create(), it works for the Store, but I can't save products because it's not persisted...
Is it possible to use multiple save in factories like this ?
Your code may need a little refactoring as you may be chaining creation of models incorrectly:
factory(\App\Models\Merchant::class, 2)->create([
'email' => 'admin#domain.com',
])->each(function ($m) {
$store = factory(\App\Models\Store::class)->create(['merchent_id' => $m->id]);
factory(\App\Models\Product::class, 10)->create(['store_id' -> $store->id]);
);
});
Note: In order to use the ->each() method, you need to have a collection instance. I do not think creating only one merchant will return a collection. In the example, we create 2 merchents.

Resources