Why stored duplicate rows to table - laravel

I have custom query for adding parsed remote posts to table:
foreach ($parsedPosts as $post) {
$hasRemotePostAlready = Post::where('remote_post_id', $post->id)->first();
if(null === $hasRemotePostAlready) {
$data = [
'title' => $post->title,
'description' => $post->description,
'remote_post_id' => $post->id
];
Post::create($data);
}
}
Variable $parsedPosts has more then 3500 posts and when I run my script to add posts then any remote posts duplicated. Why they posts duplicated and why not work my condition:
$hasRemotePostAlready = Post::where('remote_post_id', $post->id)->first();
How I can fix duplicating rows problem in my case?

You can use firstOrCreate or updateOrCreate methods for this case, take a look at the documentation
In your case try this:
$hasRemotePostAlready = Post::firstOrCreate(
[
'remote_post_id' => $post->id // columns to check if record exists
],
[
'title' => $post->title,
'description' => $post->description
]
);

Related

make better code in laravel many to many relation

hi i wrote this code and it works just fine but i think its not the best way to do it!
i want to get all the jobs for 1 company.
each company can have many addresses and each address can have many jobs
here is my code:
$company = Company::find($id)->with('addresses.jobDetails.job')->first();
$jobs = [];
foreach ($company->addresses as $address) {
foreach ($address->jobDetails as $detail) {
array_push($jobs, [
'id' => $detail->job->id,
'title' => $detail->job->title,
'country' => $detail->job->country,
'city' => $detail->job->city,
'type' => $detail->job->type,
'work_types' => JobType::where('job_id',$detail->job->id)->pluck('title'),
'income' => $detail->income,
]);
}
}
return $jobs;
can anyone help me to change this to better code please
thank you in advance
You do the opposite and start with JobDetails
$jobDetails = JobDetail::whereHas('address.company', function($companyQuery) use($id) {
$companyQuery->where('id', $id);
})->whereHas('jobs', function($jobQuery) {
$jobQuery->where('is_active', 1);
})->with('jobs')->get();
foreach ($jobDetails as $detail) {
array_push($jobs, [
'id' => $detail->job->id,
'title' => $detail->job->title,
'country' => $detail->job->country,
'city' => $detail->job->city,
'type' => $detail->job->type,
'work_types' => JobType::where('job_id',$detail->job->id)->pluck('title'),
'income' => $detail->income,
]);
}
return $jobs;
EDIT:
In your query
Company::find($id)->with('addresses.jobDetails.job')->first();
You run 4 queries with eager loading. one for each model. You can check in the result that you got that all the data is present in the variable $company.
The example I gave you it runs only two queries, the first one (job_details) will use joins to filter the Job results by the id of the companies table (you can make it faster by using the field company_id in the addresses table)
The second one is for the jobs relation using eager loading.

updateOrcreate() record new data when i update existing data

I want to use method updateOrcreate(), when data is an empty new record to the database, but when data is existing is updated data,
like image bellow data is empty I want to record new data to database
like image bellow data is existing I want to update existing data and record to database
this is my code
public function simpanDataUn(Request $request)
{
$mapel_ujian_id = $request->mapel_ujian_id;
for($i=0; $i < count($mapel_ujian_id); $i++)
{
$arr = NilaiUjianAKhir::updateOrCreate([
'sekolah_id' => \Auth::user()->sekolah_id,
'siswa_id' => $request->id,
'mapel_ujian_id' => $request->mapel_ujian_id[$i],
'nilai_standar_daerah' => $request->nilai_standar_daerah[$i],
'predikat_standar_daerah' => $request->predikat_standar_daerah[$i],
'nilai_sekolah' => $request->nillai_sekolah[$i],
'predikat_nilai_sekolah' => $request->predikat_nillai_sekolah[$i],
'nilai_akhir' => $request->nilai_akhir[$i],
'predikat_nilai_akhir' => $request->predikat_nilai_akhir[$i],
],
[
'nilai_standar_daerah' => $request->nilai_standar_daerah[$i],
'predikat_standar_daerah' => $request->predikat_standar_daerah[$i],
'nilai_sekolah' => $request->nillai_sekolah[$i],
'predikat_nilai_sekolah' => $request->predikat_nillai_sekolah[$i],
'nilai_akhir' => $request->nilai_akhir[$i],
'predikat_nilai_akhir' => $request->predikat_nilai_akhir[$i],
]);
}
return redirect()->back()->with('success', 'Data UN berhasil di input');
}
I'm using updateOrCreate()method, but when i UPDATED existing data, the data
and even create new data, not updated existing data, like image below:
What part is wrong from my code? how to updated existing data using updateOrCreate() method?
please help me, thanks
Maybe you can change your code like this :
public function simpanDataUn(Request $request)
{
$mapel_ujian_id = $request->mapel_ujian_id;
for($i=0; $i < count($mapel_ujian_id); $i++)
{
$arr = NilaiUjianAKhir::updateOrCreate([
'sekolah_id' => \Auth::user()->sekolah_id,
'siswa_id' => $request->id,
'mapel_ujian_id' => $request->mapel_ujian_id[$i],
],
[
'nilai_standar_daerah' => $request->nilai_standar_daerah[$i],
'predikat_standar_daerah' => $request->predikat_standar_daerah[$i],
'nilai_sekolah' => $request->nillai_sekolah[$i],
'predikat_nilai_sekolah' => $request->predikat_nillai_sekolah[$i],
'nilai_akhir' => $request->nilai_akhir[$i],
'predikat_nilai_akhir' => $request->predikat_nilai_akhir[$i],
]);
}
return redirect()->back()->with('success', 'Data UN berhasil di input');
}
Like #lagbox say the first array passed to updateOrCreate are the where conditions to find a record ... if it can't find a record by those conditions it will create a new one. You won't create the new one when there's same sekolah_id, siswa_id or mapel_ujian_id right? Then the other field can be updated

How to save multiple rows to multiple database tables at onces

For example i have "id, name, wage, sex, age" columns.
1, John, 3, M, 30
2, Angela, 5, F, 26
If i have 50 rows like this. And if i want to save name, wage into table1 & sex and age into table2. In laravel docs queries/insert, they told us make an array and put values on it. But how should i put some of the values into table1 and other values into table2 in same foreach.
foreach($test as $tests)
{
$data[] =[
'name' => $tests->name,
'wage' => $tests->wage,
'sex' => $tests->sex,
'age' => $tests->age
];
}
Products::insert($data);
Is this the right ways to do it? I cant figure out the correct way to do.
If these tables are not related, you can do it with just 2 queries:
foreach ($tests as $test) {
$products[] = [
'name' => $tests->name,
'wage' => $tests->wage
];
$otherData[] = [
'sex' => $tests->sex,
'age' => $tests->age
];
}
Products::insert($products);
OtherModel::insert($otherData);
In case if these models are related, you'll need to create 51 query instead of 2 (still better than 100 queries):
foreach ($tests as $test) {
$productId = Products::insertGetId([
'name' => $tests->name,
'wage' => $tests->wage,
]);
$otherData[] = [
'sex' => $tests->sex,
'age' => $tests->age,
'product_id' => $productId
];
}
OtherModel::insert($otherData);
If these models are related and you still want to do this with just a few queries, you could use transactions:
DB::transaction(function () {
$productId = (int)DB::table('products')->orderBy('id', 'desc')->value('id');
foreach ($tests as $test) {
$productId++;
$products[] = [
'name' => $tests->name,
'wage' => $tests->wage
];
$otherData[] = [
'sex' => $tests->sex,
'age' => $tests->age,
'product_id' => $productId
];
}
Products::insert($products);
OtherModel::insert($otherData);
});
you could loop trough data and insert into DB table.
foreach($test as $tests)
{
$product = new Products();
$product->name = $tests->name;
$product->name = $tests->name;
$product->save();
$another = new AnotherTableModel();
$another->sex= $tests->sex;
$another->age= $tests->age;
$another->save();
}

Avoid duplication in doctor_id field with where clause in laravel 5.4

this is my doctors id
this is my user id
I can't insert anything when I put unique in the validation of doctor_id. When there's no unique it works fine.
I want to avoid duplicate doctor_id where auth::id == 1. Any advice is appreciated.
public function store(Request $request, $id)
{
$auth = Auth::id();
$constraints = [
'doctor_id' => 'required|unique',
'day1' => 'required|max:20',
'day2'=> 'required|max:60',
'day3' => 'required|max:60'
];
$input = [
'users_id' => $auth,
'doctor_id' => $id,
'day1' => $request['day1'],
'day2' => $request['day2'],
'day3' => $request['day3'],
'day4' => $request['day4'],
...
'day27' => $request['day27'],
'status' => '1'
];
$this->validate($request, $constraints);
Itinerary::create($input);
$added = array('added'=> 'Added Doctor to Itinerary Successful!!');
return redirect()->back()->with($added);
Have you tried this? (assuming your table is named itineraries):
'doctor_id' => 'unique:itineraries'
According to Laravel Doc, you should add the table name, and column name if possible:
unique:table,column,except,idColumn

Laravel UpdateOR Create not work with relationship

I want to update my related table on laravel 5.4
my code
$id = $request->id;
$find = Presal::find($id);
$find->user_id = $request->customer_id;
$find->proposalid = $request->proposalid;
$psal = $find->save();
if ($psal) {
foreach ($request->service_item_id as $key => $n) {
$find->proposalService()->updateOrCreate([
'service_item_id' => $request->service_item_id[$key],
'start_date' => $request->start_date[$key],
'end_date' => $request->end_date[$key],
'service_type_id' => $request->service_type_id[$key],
'vendor_submit' => $request->vendor_submit[$key],
]);
}
}
Here always my code create a new row in proposalService but not update.
How can I make create if new and Update if exist.
updateOrCreate() takes 2 arguments (2 arrays). First array, you pass the element you want to check, usually the primary key and some other element. It then checks if those elements exist, else, create a new one.
$find->proposalService()->updateOrCreate(
[
'service_item_id' => $request->service_item_id[$key],
'service_type_id' => $request->service_type_id[$key]
],
[
'start_date' => $request->start_date[$key],
'end_date' => $request->end_date[$key],
'vendor_submit' => $request->vendor_submit[$key]
]
);
Here I used service_item_id and service_type_id as first argument to check if they already exist.

Resources