Deekshith's avatar

Larvael insert hasmany relationship

i have a tables like below,

  1. submission
id, uuid, abstract, status, user_id
  1. submission_figures
id, submission_id,figure_name,figure_title

So here the relatisonip is,

public function figures()
    {
    	return $this->hasMany('App\Models\SubmissionFigure','submission_id','id');
    }

One submission may have many figures lets say single submission has 100 figures.

Now what i am doing is there is a revision process. at first submission will be empty for a user. first he enters all the details and upload all the figures and data will be inserted to submission and figures tables and status for that submission will be set as Active.

Now admin verifies the submission and enable the resubmit article button if it needs correction and admin will give option to edit the previous submission and i want to keep track of every changes. so once user clicks on resubmit submission i am using previous active submission and inserting again to same table like below,

  $activearticle = ResubmitArticle::where('status','=','Active')->where('user_id',auth()->user()->id)
                                        ->first();

$newdata = [
          'uuid' => unique_str('App\Models\ResubmitArticle', 'resubmit_uuid'),
          'user_id' => $activearticle->user_id,
          'abstract' => $activearticle->abstract,
          'status' => 'Active',
        ];
$newinserteddata = ResubmitArticle::create($newdata);

Here previous submission status will be changed to History and newly created one will be changed to Active.

at a time only one active submission will be there which will be parent source for next edit purpose..

now i want to insert figures of $activearticle

i have tried below code,

$figuredata = $activearticle->figures;
        foreach($figuredata as $data)
        {
        	$figdata = [
            'article_submission_id' => $data->article_submission_id,
            'resubmit_article_id'=>$newinserteddata->id,
            'figure_name' => $data->figure_name,
          ];

          SubmissionFigure::create($figdata);
        }

This is working fine but my concern is speed if the submission has more than 200 Images then i think foreach will take time to insert all the images . any other solution to achieve this?

0 likes
10 replies
Deekshith's avatar

to generate that array i should do foreach over data right?

frankielee's avatar

Oh, just noticed you are formatting the data by using the foreach loop.

Think so, unless the data is already formatted.

frankielee's avatar

@deekshith

Try this: https://laravel.com/docs/8.x/collections#method-map, Example:

$collection = collect( $activearticle->figures);
$data = $collection->map(function ($data, $key) use ($newinserteddata) {
      'article_submission_id' => $data->article_submission_id,
       'resubmit_article_id'=>$newinserteddata->id,
       'figure_name' => $data->figure_name,
});
          SubmissionFigure::create($data);


Deekshith's avatar

@frankielee Thank you. i have a requirement like below,

At first authors submits the article and initially i am storing this in below table,

id,uuid,abstract,running_title,status,user_id

And also every article submission hasMany figures which has table structure like below,

id, submission_id,figure_name,

And also every article submission hasMany Table files which has table structure like below,

id, submission_id,table_name,

And also every article submission hasMany authors details which has table structure like below,

id, submission_id, name,email,mobile

So the data will be submitted to all these tables on first submit.

Now admin will update the status to resubmit the previously submitted article for corrections. i can edit previous submission but i want to maintain history so i tried to create the exact copy of data and files which will be automatically imported in same tables with different resubmit_article_id once user clicks on resubmit article.

But above foreach method causes slowness if it has more data. do you recommend any other way to keep history of every edit by creating new entry? or do you have any flow i can follow? Thank you.

Deekshith's avatar

@frankielee Thank you for the reply as i am using shared hosting i think it will be not possibe to run php artisan queue:work command so that's the problem. can we dispatch that queue without running that command using any code?

Deekshith's avatar

Also what about using lazyloading along with chunks instead of createMany?

frankielee's avatar

can we dispatch that queue without running that command using any code?

To let the queue running as a background process, no.

Also what about using lazyloading along with chunks instead of createMany?

Both of these are used to optimize memory usage, don't help in reducing the time taken of the foreach loop.

Btw, have you monitored the time taken of the whole function? the total time taken of the whole request to return result to user? and which step took the longest time?

Please or to participate in this conversation.