Eloquent Laravel : creating a counter with foreach loop - laravel

using Laravel's Eloquent, I'm trying to add an incremental counter to certain rows based on their 'product_id'.
I thought I could do it like this :
$foos = GanttTask::where('product_id',1)->orderBy('date', 'ASC');
$counter = 1;
foreach($foos as $foo){
$foo->custom_counter = $counter;
$counter +=1;
}
return $foos->get();
But this is of no effect on my data, custom_counter column doesn't change (but I get no error).
I tried to add $foo->save() within my loop with no effect.

Get first all record and then modify single record using save method like this:
$foos = GanttTask::where('product_id',1)->orderBy('date', 'ASC')->get(); // Get All records
$counter = 1;
foreach($foos as $foo){
$foo->custom_counter = $counter;
$counter +=1;
$foo->save(); // Update each record
}
Good Luck !!!

To actually update the database, I reckon you need to persist each data object foo individually not the collection foos as a whole.
$foos = GanttTask::where('product_id',1)->orderBy('date', 'ASC');
$counter = 1;
foreach($foos as $foo){
$foo->custom_counter = $counter;
$counter +=1;
$foo->save(); // Persisting data here
}

Related

Backpack for Laravel charts, append sum to chart

As I'm trying to implement charts into Backpack for Laravel, I been stuck for a few hours on this problem. The following script gets the number of users created for each day and appends them to an array that is then shown on the charts.
for ($days_backwards = 7; $days_backwards >= 0; $days_backwards--) {
// Could also be an array_push if using an array rather than a collection.
$users = Users::whereDate('created_at', today()->subDays($days_backwards))->count();
$user[] = $users;
}
Every iteration of the loop adds a number to the array (or is it a collection??) so something like [2,5,10,9,...].
I would rather like to get the total amount of users that ever registered, incrementally for each day, so that the result would be someting like [2,7,17,26,...].
I figured I could add each iteration with array_sum() but it's not working. Is it an array anyways? Is there a way to append to this list the sum to its previous?
Well I kind of figured out!
$sum = 0;
for ($days_backwards = 7; $days_backwards >= 0; $days_backwards--) {
$users = Users::whereDate('created_at', today()->subDays($days_backwards))->count();
$sum = $sum + $users;
$user[] = $sum;
}
It works!

see value according to the array

I do a select and get several results in array but I need to get the correct value for each step and set up a condition.
$step = DB::table('records')->where('id_user',$userId)->get();
for($i = 0; $i < count($step); $i++)
{
echo $step[$i]->id_step;
}
Id_step returns me values for each step where on the blade I need to get and see if id_step = 1 is true id_step = 2 is true.
This for is returning me only one value and it has 3 records in the table.
First of all. After a select you get an instance of Eloquent\Collection
Not an array.
So that said to loop do this:
$steps = DB::table('records')->where('id_user',$userId)->get();
foreach($steps as $row) {
echo $row;
}
Since you are familiar with arrays do this:
$steps->toArray();
Now your result is an array
Working insert in view this code.
#for($i = 0; $i < count($step); $i++)
#if($step[$i]->id_step == 2)
working
#else
not working
#endif
#endfor

generate more than one random code in laravel and save it to database

I'm a newbie in laravel. I have to generate multiple random characters at once in my laravel project and then save them to database. Any example or advise that quite easy to understand? thank you
A for loop may be appropriate for you in this case. If you don't have an object for the codes, you can do something like this:
$total_wanted = 100;
for ( $i = 0; $i < $total_wanted; $i++ ) {
DB::table('codes')->insert(['code' => uniqid("prefix")]);
}
If you do have a Code object, you can do it like this instead:
$total_wanted = 100;
for ( $i = 0; $i < $total_wanted; $i++ ) {
$code = new Code;
$code->code = uniqid("prefix");
$code->save();
}
echo uniqid('code_', true);
You generate a random, unique string based on current timestamp, so it can not be a duplicate.
Then simple store it in the database as a varchar
More about this function here

Laravel 5 - how to get a random row from first 30 records in eloquent?

I am trying to get a random row from the top 30 records in a table. I sort all the records by score first, and take 30 records in a scope of the eloquent model:
public function scopePopular($query, $d)
{
return $query->where('d', $d)->orderBy('score', 'desc')->take(30);
}
Then in a class:
$cnt = Record::popular($d)->count();
if ($cnt == 0)
return;
$randIndex = rand(0, $cnt-1);
$record = Record::popular($d)->skip($randIndex)->take(1)->first();
return $record;
But when I check in php artisan tinker, I found that Record::popular($d)->count(); will return all the records number instead of 30. How can I correct this problem? Thanks.
Use get() before count() to run the query before count:
$cnt = Record::popular($d)->get()->count();
You are running the query 2 times. That is not necessary.
$cnt = Record::popular($d)->count(); // First query
if ($cnt == 0)
return;
$randIndex = rand(0, $cnt-1);
$record = Record::popular($d)->skip($randIndex)->take(1)->first(); // Second query
return $record;
Instead you can do it like this:
return Record::popular($d)->get()->random(); // One query only

How to optimize saving multiple models?

I need to manually save a very large number of order items to the database. I'm currently doing something like this:
for($x=0; $x<250000; $x++)
{
$orderItem = Mage::getModel('sales/order_item');
$data = array('a'=>1, 'b'=>2, 'c'=>3);
$orderItem->setData($data)->save();
}
Attempting to run this code from a shell script takes forever. What strategies can I use to speed up this code?
I'm not sure but take a look # Mage::getModel('core/resource_transaction')
See https://stackoverflow.com/a/4879133/1191288
You could try doing a batch save on ever X amount
$batch = 500;
$orderItem = Mage::getModel('sales/order_item');
$transactionSave = Mage::getModel('core/resource_transaction');
for($x=0; $x<250000; $x++){
$orderItem->setData( array('a'=>1, 'b'=>2, 'c'=>3));
$transactionSave->addObject($orderItem);
$orderItem->reset()
if ($x % $batch == 0){
$transactionSave->save();
$transactionSave = null;
$transactionSave = Mage::getModel('core/resource_transaction');
}
}
if($x % $batch > 0)
$transactionSave->save();
I think in this situation, your best bet to speed this up significantly would be to create custom database queries.
Edit: Related option: try to rewrite the model and resource model to implement a method bulkSave() which is like save() but only creates the corresponding query object and returns it, so it does not actually use the database. Then collect all the queries and run them in big transactions every thousand items or so.

Resources