Laravel How to increment only when its a new insert? - php

I need to increment 'total_products' field in Categories table every time a new product is added. But I don't want it to increase when an existing product is UPDATED. I'm doing this right now:
Category::findOrNew($product->cat_id)->increment('total_products',1);
But this code doesn't recognize whether its an update or a new insert. It increases 'total_products' no matter its an insert or update. How can I make it increment only when its a new insert?

It is clearly two query, try each with separate query
$cat = Category::find($product->cat_id);
if($cat){
$cat->increment('total_products',1);
}else{
$cat = new Category();
$cat->total_products = 1;
// Inert new category here with all related data
$cat->save();
}
return $cat->id;
Also be sure about when to increase total_products ? after insert or after update.

Use the firstOrCreate method for that:
$category = Category::firstOrCreate(['name' => 'John Doe']);
If you want to know whether the user was created or fetched, check the wasRecentlyCreated property:
if ($category->wasRecentlyCreated) {
// "firstOrCreate" didn't find the user in the DB, so it created it.
} else {
// "firstOrCreate" found the user in the DB and fetched it.
}

You can set total_products field to 0 by default in the migration:
$table->integer('total_products')->default(0);
Then findOrCreate and increment:
Category::query()
->findOrCreate($product->cat_id)
->increment('total_products');

Related

How to make multiple where clause and get just only the first

I tried to accomplish a multiple where clause but failed. I want to check if the current Date of the user is equal to created_at and the second clause would be if the user has an entry by user id. I am working on a fitness app where the User can track the km he has run. And rather to create in a database table new entries just add them to the existing entries.
My Question is focused on the problem with the if clause because the variable $hasUserEntries is not equal to null but there is no entry in the database table. It is empty.
I tried instead of using get() I used first(). But the problem is that I wasn't able to use Carbon::today() or it was maybe that I use 3 values in the where clause which I need because I can't get the created_at date only the Date YYYY-MM-DD. At the first() Statement I used a hardcoded DateTime to check with created_at and it worked. But I think I must not explain why hardcode is not optimal.
I searched on Stackoverflow and find that most answers were about using get(). It is fine but why does my else get triggered because from my point of view the database is empty(Null) so the if($hasUserEntries==null)should be triggered.
public function add_km_to_progressbar(Request $request, TrackKM $trackKM)
{
$track_dailies = new TrackDaily();
$track_dailies->user_id = \Auth::user()->id;
$amount_runned_km = $request->input('amount_runned_km');
$amount_runned_km = (int)$amount_runned_km;
$track_dailies->amount = (int)$amount_runned_km;
$track_dailies->type = 1;
$check_requirements = [
'user_id'=>\Auth::user()->id,
'created_at'=>'Carbon::today()'
];
$hasUserEntries = DB::table('track_dailies')
->where('user_id','=',\Auth::user())
->where('created_at','>=',Carbon::today())
->get();
if ($hasUserEntries == null) {
return dd('does not work');
} else {
return dd('does work');
}
}
Expected Result should be the triggering of the if statement because if the database table is empty, the user id does not exist or the date of created_at is not the same as the current date then should be triggered if($hasUserEntries==null). I want to create there a new row if this condition == null in the database.
Actual Result if($hasUserEntries==null) is true even though that the database table is empty. I think that the method get() has values saved that are not related to the database.
I hope that you can help me out.
i think what you should have done is checking to see if the record exist in the database before proceeding...
$checkifuserExist= DB::table('track_dailies')->where('user_id','=',\Auth::user())->where('created_at','>=',Carbon::today())->count();
if($checkifuserExist>0)
{
//proceed to query for fitness
}
else
{
//do something else...
}
with this, it will not throw error!
Try this if case intead:
if (is_empty($hasUserEntries))
$checkifuserExist= DB::table('track_dailies')->where('user_id','=',\Auth::user())->where('created_at','>=',Carbon::today())->count();
if($checkifuserExist>0)
{
//if user really exists
if( $hasUserEntries = DB::table('track_dailies')->where('user_id','=',\Auth::user())->where('created_at','>=',Carbon::today())->first())
{
//update the value of the amount
}
else{
//insert new record
}
}
else
{
// if the user does not exist, do something else...
}
remember theres no way the record for user_id would be null because first there has to be record inside the db

Update data into table from dynamically created input field

I have 2 models Tour.php
public function Itinerary()
{
return $this->hasMany('App\Itinerary', 'tour_id');
}
and
Itinerary.php
public function tour()
{
return $this->belongsTo('App\Tour', 'tour_id');
}
tours table:
id|title|content
itineraries table:
id|tour_id|day|itinerary
I have used vue js to create or add and remove input field for day and plan dynamically. And used the following code in tour.store method to insert into itineraries table:
$count = count($request->input('day'));
$temp_day = $request->input('day');
$temp_itinerary = $request->input('itinerary');
for($i = 0; $i < $count; ++$i)
{
$itinerary = new Itinerary;
$itinerary->tour_id = $tour->id;
$itinerary->plan = $temp_itinerary[$i];
$itinerary->day = $temp_day[$i];
$itinerary->save();
}
And was successful in inserting the records.And applied same code in tour.store method. Instead of updating the rows, it inserted new rows to the table. What would be the best solution for this ?
For updation try this code
$itinerary = Itinerary::find($tour_id);
$itinerary->plan = $temp_itinerary[$i];
$itinerary->day = $temp_day[$i];
$itinerary->save();
The way you are using is to insert/create new records. To update you can use.
Itinerary::find($tour_id)->update(
['column_name'=> value]
);
Where find method takes a primary key of the table.
This will update your existing record. You can update as many columns as you want just pass in array update takes. You can also use save method as mentioned in other answer.
Check Laravel Update Eloquent
EDIT
$iterneary = Itenerary::where('tour_id', $tour_id)->first();
Now you can update this iterneary object to whatever you want.
this is how i did it. First saved all the tours in $tours[] array.
foreach($tours as $tour) {
$itinerary->tour()->updateOrCreate(['id'=> $tour['id']],$tour);
}
updateOrCreate because you may need to add new tours while updating. I know this doesnt answer your issue exactly but this could atleast give you an idea.

Want to delete all record as per id and then insert in laravel

I want to delete all record according to id and then insert record in same table,I tried many ways but can't find solution please help me.
Basically as per the document id i want to delete all document but it is not working.
Here is my controller code:
foreach ($receievers as $user) {
$this->shareRepo->deleteSharedDoc($resourceId);
$this->shareRepo->saveshareSharedDoc($resourceId, $user->id,$this->getCurrentUser());
}
The repository code:
function saveSharedDoc($resourceId, $sharedWith, $resourceOwnerId){
$shareDocs = new ShareDocs;
$shareDocs->resource_id = $resourceId;
$shareDocs->shared_with = $sharedWith;
$shareDocs->user_id = $resourceOwnerId;
$shareDocs->shared_on = $this->getCurrentDateTime();
$shareDocs->token = str_random(20);
$shareDocs->save();
return $shareDocs->token;
}
function deleteSharedDoc($resourceId){
$network = ShareDocs::where('resource_id','=',$resourceId);
$result=$network->delete();
return $result;
}
Please help me out
It's seems you're doing it correctly. But there are two things that you have to change.
You are calling to saveshareSharedDoc method within foreach loop to save data. but actual method name on your repo is saveSharedDoc. (there two "share" words on loop)
you can return deleted rows directly return ShareDocs::where('resource_id', $resourceId)->delete();

codeigniter dynamic field added on migration time

i have two database called "migrate_new" and "migrate_old" and both have one table called "cms_pages".
i want to compare "migrate_old" db "cms_pages" with the "migrate_new" "cms_pages" table structure if "migrate_new" database "cms_pages" does not have "field" then alter table automatically.
below is my code to compare "migrate_old" "cms_pages" fields not in
"migrate_new" "cms_pages" now i want to add this fields on table.
i want to continue the process in place of exit.
**> any one can have idea to add fields automatically so no need to stop
migration task?
i am not able to get field details like type , key , etc.
how i know alter table with use modify or add fields.
i short i want to set structure with out loss of any data automatically.
thanks in advance..
**
$this->load->database();
$admin_db = $this->load->database('ADMINDB', TRUE);
$query = $this->db->get('cms_page');
$result = $query->result();
$fields_old = $this->db->list_fields('cms_page');
// $fields_new = $admin_db->list_fields('cms_page');
$flag = false;
foreach ($fields_old as $field){
if (!$admin_db->field_exists($field, 'cms_page'))
{
echo $field.'=> is not exists in new table please contact to developer for that <br>';
$flag = true;
}
}
if($flag){
exit;
}

How to check if data is already in database using PHP?

Situation:
My PHP script will run once a way.
and that will store data in my database.
Since 1 week is good enough for me, so I only want to keep just that.
Let's say if today is Friday OR 5 (in my case).
Is there a way to check if date == 5 is already exist in the database, and possibly override it with the one ?
If today is Friday/5, then all the old data with date == 5 should be overridden and store the new one instead.
Literally, I only want to store one full week worth of data.
Tomorrow, and the next will repeat the same logic.
Here is how I insert my data into my database :
$data = new Data;
$data->name = $name;
$data->description = $description;
$data->dayOfWeek = $today; // could be 0,1,2,3,4,5,6
$data->save();
I am not sure, how do I accomplish that in Laravel.
Any tip/suggestion will be much appreciated !
Why don't you do this outside of your foreach loop - before you insert
Data::where("dayOfWeek","=", $today )->delete();
That should take care of what you want, then you can continue insert just like normal:
$data = new Data;
$data->name = $name;
$data->description = $description;
$data->dayOfWeek = $today; // could be 0,1,2,3,4,5,6
$data->save();
You can use INSERT ... ON DUPLICATE KEY UPDATE eg. like that
INSERT INTO `data` (`name`, `description`, `day`) VALUES (:name, :description, :day)
ON DUPLICATE KEY UPDATE name = VALUES(name), description = VALUES(description)
Of course you have to declare unique key on day field to make it work.
If you specify ON DUPLICATE KEY UPDATE, and a row is inserted that would cause a duplicate value in a UNIQUE index or PRIMARY KEY, an UPDATE of the old row is performed. For example, if column a is declared as UNIQUE and contains the value 1, the following two statements have identical effect:
Sample Code:
INSERT INTO table (a,b,c) VALUES (4,5,6)
ON DUPLICATE KEY UPDATE c=9;
Firstly get the data from the database;
$data = Data::where('dayOfWeek', $today)->first();
Then check to see if the data is there, if it is update if not create.
if (!is_null($data)){
$data->update($new_attribute_data)
}
else {
Data::create($new_attribute_data);
}
As a note: Using the update method can require you to fill the $fillable array within your model if you putting GET or POST data into it. You can do it like so;
class Data extends Eloquent {
...
protected $fillable = ['name','description','dayOfWeek'];
}
And Laravel will fill the Model Attribute with the corresponding data within the Input.
EDIT:
As a faster way for the above method, use the updateOrCreate method;
Data::updateOrCreate(['dayOfWeek' => $today], $new_attribute_data);
This will search for Data models with attributes that match the first parameters, and will update its other attributes with the second parameter. Ref

Categories