I have a function that gets $homes and $member_id as parameters. $homes is an array, $member_id is an integer.
$homes = array( 'home13', 'home21', 'home34', 'home44' );
$member_id = 5;
How do I insert/update into the following DB?
in the format:
id home_name member_id
1 home13 5
2 home21 5
2 home34 5
2 home44 5
The function I used:
public function store($homes, $member_id) {
foreach( $homes as $home ) {
$data[] = [ 'member_id' => $member_id, 'home_name' => $home ];
}
Home::insert( $data );
}
which works fine while inserting. However, I need to update all records for a given $member_id if the member_id already exists.
For example, if the $member_id is 5 and $homes is now array( 'home54' ), all other home_name that are previously stored for the $member_id 5 should be deleted. so that the following would only remain.
id home_name member_id
1 home54 5
You can use Laravel's upsert() method
Example:
Home::upsert([
['home_name' => 'home54', 'member_id' => 5, 'id' => 1],
['home_name' => 'home13', 'member_id' => 5, 'id' => 2],
['home_name' => 'home21', 'member_id' => 5, 'id' => 3],
], ['member_id', 'id'], ['home_name']);
This method consists of three arguments.
Values to insert/update
Columns that uniquely identify the values
The values that need to be updated
Please note that you need to use a unique composite key to use upsert() method.
Example from Seeder class:
$table->unique(['member_id','id']);
Reference from Laravel docs: https://laravel.com/docs/9.x/eloquent#upserts
You can use updateOrCreate method to achieve this
public function store($homes, $member_id) {
foreach( $homes as $home ) {
Home::updateOrCreate( 'member_id' => $member_id, 'home_name' => $home );
}
}
Related
How can I get data by grouping user_id for a foreach loop in a controller's function in Laravel. For example, user_id = 2, 5 rows available, user_id = 1, 10 rows available. Then show 2 arrays.
$lists = lists::wherestatus(1)->groupby('user_id')->get();
foreach($lists as $list){
$list = functionHere;
}
What function can I create for this on the controller for grouping?
I need more information, but based on what you shared, you should be able to do this (removing the foreach):
$lists = Lists::whereStatus(1)->get()->groupBy('user_id');
The difference is that if you use groupBy before get, you are grouping your query by user_id, so instead of getting 5 rows for user_id = 2 and 10 for user_id = 1, you are going to get 2 rows and just the latest data, so you need to use Collection's groupBy.
What you want to do is group all the information by user_id but have each row, a schema like this:
[
'1' => [ // user_id
['user_id' => '1', 'column1' => 'random value'],
['user_id' => '1', 'column1' => 'other value'],
// 8 remaining rows
],
'2' => [ // user_id
['user_id' => '2', 'column1' => 'other nice value'],
// 4 remaining rows
],
]
you should first in List model set:
public function scopeStatus(){
return $this->where('status','1');
}
and in your controller:
$products = List::status()->groupby('user_id')->get();
How to use updateOrCreate with hasMany relationship. For example I have first model Code:
class Code {
public function item()
{
return $this->hasOne(UserItem::class, 'code_id')
}
}
And for the nested relationship UserItem:
class UserItem {
public function serials()
{
return $this->hasMany(ItemSerial::class, 'user_item_id', 'id');
}
}
And I need to updateOrCreate values of serials relationship. I tried this:
foreach ($data['item_serials'] as $serial) {
$code->item->serials()->updateOrCreate([
'serial' => $serial
]);
}
But this doesn't work how I need, because it changes both serial values to same value. This is how serials table looks like:
id user_item_id serial
1 1 lorem
2 1 ipsum
And then I recieve request:
'item_serials' =>
array (
0 => 'test1',
1 => 'test2',
2 => 'test3'
),
And with this request I want to update serials table like this:
id user_item_id serial
1 1 test1
2 1 test2
3 1 test3
I hope I explained understandably. How I should approach this?
Update or create takes two arguments
1-updated data
2-condition
like
$flight = Flight::updateOrCreate(
['departure' => 'Oakland', 'destination' => 'San Diego'],
['price' => 99, 'discounted' => 1]
);
see the docs https://laravel.com/docs/8.x/eloquent
Add an array as the first argument inside updateOrCreate(), it'll be used to retrieve/find an existing serial if it does update but if not then create it.
foreach ($data['item_serials'] as $serial) {
$code->item->serials()->updateOrCreate(
['serial' => $serial],
['serial' => $serial]
);
}
I have a store function that saves array items into my items table and together with that I am trying to check if the product_is is already in my Warehouse1StockSummaries. if still not, I will grab the product_id and its qty, If its there already then I want to ADD the value from the 'stock_in_qty' which is inside the array to the 'qty_in' in my Warehouse1StockSummaries. I hope my explanation make sense to you :)
here's my code.
public function store(Request $request)
{
$input = $request->all();
$items = [];
for($i=0; $i<= count($input['stock_in_qty']); $i++) {
if(empty($input['stock_in_qty'][$i]) || !is_numeric($input['stock_in_qty'][$i])) continue;
$acceptItem = [
'order_id' => $input['order_id'][$i],
'product_id' => $input['product_id'][$i],
'order_item_id' => $input['order_item_id'][$i],
'delivery_date' => $input['delivery_date'][$i],
'company_id' => $input['company_id'][$i],
'stock_in_qty' => intval($input['stock_in_qty'][$i]),
'stock_out_qty' => $input['stock_out_qty'][$i],
'transfer_to' => $input['transfer_to'][$i],
'delivery_note' => $input['delivery_note'][$i],
'user_id' => $input['user_id'][$i]
];
$product_id = $input['product_id'][$i];
$qty_in = intval($input['stock_in_qty'][$i]);
// dd($qty_in);
// ADD stock_in_qty TO QTY_IN ????
$stockSummary = Warehouse1StockSummaries::updateOrCreate(
['product_id' => $product_id ],
['qty_in' => $qty_in,
'qty_out' => null
]);
// dd($stockSummary);
array_push($items, Warehouse1stocks::create($acceptItem));
}
return redirect()->route('orders.index');
}
I check and everything is ok the only missing is the part where I need to grab the value from 'stock_in_qty' and add to 'qty_in' if the product id is already found in Warehouse1StockSummaries. Thank you so much in advance!
You could use the wasRecentlyCreated property on the model to determine if the model has just been created or not. If it hasn't then it won't have used $qty_in value, this means you could then use the increment() to add to the existing value in the database:
$stockSummary = Warehouse1StockSummaries::firstOrCreate(
['product_id' => $product_id ],
['qty_in' => $qty_in, 'qty_out' => null]
);
if (!$stockSummary->wasRecentlyCreated) {
$stockSummary->increment('qty_in', $qty_in);
}
Array to string conversion
(SQL)
`insert into `group_members` (`id`, `group_id`, `alias`) values (1, 20, Lilian Marvin PhD)`
$users = User::where('role_id','=',3)->select('id','display_name')->get();
foreach ($users as $user) {
$groups = Group::select('id')->get()->toArray();
// echo $user->display_name ." " .$user->id ."<br/>";
DB::table('group_members')->insert([
'id' => $user->id,
'group_id' => array_random($groups),
'alias' => $user->display_name
]);
}
in the array_random, I believe there's an error
You are trying to save array in group_id column. You need to save only id not array
try this
DB::table('group_members')->insert([
'id' => $user->id,
'group_id' => array_random($groups)['id'],
'alias' => $user->display_name
]);
If you want to get any one of the group then you can try
array_random($groups, 1),
if you want to store multiple, then you may like to convert it to json
json_encode(array_random($groups, 1)),
used laravel helper method Arr::random
The Arr::random method returns a random value from an array
use Illuminate\Support\Arr;
$array = [1, 2, 3, 4, 5];
$random = Arr::random($array);
// 2 - (retrieved randomly)
When I insert a new record into a database table, I need to take an existing previous value of a column called el_order, add +1, and use that new el_order+1 to insert the new record with that value in the column.
I can't use autoincrement because I need to do some things with that column (reorder, move, etc) and have to use it as an integer.
Table
ID name el_order
1 1 1
21 bla 2
2 2 3
--NEW-- --NEW-- 3+1 (NEW)
I add a new record, and need to insert it with 3+1 in it's el_order column...
I have tried this, but no luck:
$this->db->select_max('el_order');
$res = $this->db->get('elem_diccio');
$eldi_key = url_title($this->input->post('id'), 'underscore', TRUE);
$el_order = $res+1;
$datos = array(
'ID' => $id,
'el_order' => $el_order,
'name' => $this->input->post('name'),
);
$this->db->insert('elem_diccio', $datos);
Just like this
$this->db->select_max('el_order');
$res = $this->db->get('elem_diccio')->row()->el_order;
$eldi_key = url_title($this->input->post('id'), 'underscore', TRUE);
$el_order = $res+1;
$datos = array(
'ID' => $id,
'el_order' => $el_order,
'name' => $this->input->post('name'),
);
$this->db->insert('elem_diccio', $datos);
$res is a CI_DB_mysqli_result Object. To get the column, you need
$this->db->select_max('el_order');
$res = $this->db->get('elem_diccio')->row();
$el_order = $res->el_order+1;
$datos = array(
'ID' => $id,
'el_order' => $el_order,
'name' => $this->input->post('name'),
);