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.
Related
I want to loop over a collection of items and attach a relationship based on if a particular condition is satisfied. Here is my code
public function bulkAssign()
{
$trainers = MasterTrainer::all();
for ($i=0; $i < count($trainers); $i++) {
$this->assignToManager($trainers[$i]);
}
// return redirect()->back()->with('success', 'Project Managers Assigned Successfully');
}
private function assignToManager($trainer)
{
$manager = ProjectManager::where('state', $trainer->state)->first();
return $trainer->update([
'project_manager_id' => $manager->id
]);
}
What I get is it attaches only the first manager to all the elements in the collection. What am i doing wrong?
can you inline the func for now? do some sort of echo/debugging?
but also I see several issues:
yes do use foreach because that is a bit better and you avoid having to use $i (making code a little more easy to read)
you are not attaching a relationship, you are setting a project_manager_id (i say this because initially i automatically thought you were going to dynamically add a relationship to model)
without knowing your db schema.. could you not do some sort of trick to avoid having to do this nth times?
$manager = ProjectManager::where('state', $trainer->state)->first();
you could either do:
$states = $trainers->pluck('states');
$managers = // do a query to get one trainer per state using group by
foreach ($trainers... ) {
$manager = $managers->where('state', $trainers->state)->first() // this is collection not eloquent
$trainer->update([
'project_manager_id' => $manager->id
]);
other would be to create a scope where you do a sub query to get manager id when u query for trainers
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');
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();
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
this is the my first post and I'm really confused with the below code. I'm building a gaming website (my first project using yii) and I'm using afterSave() in the model to insert data to another table because the relation is Many to Many. I'm fetching data from database then exploding it to get numbers only (so I can insert it in the other table) instead of ('2','|','3'). The problem is foreach is inserting one row instead (despite the fact it should insert more than one row) of two in my example and the inserted con_id value is always 1, I don't understand the issue here, please help me.
protected function afterSave()
{
$model1 = new GameConsole();
$con[] = explode('|', $this->con_id);
foreach($con as $row) {
$model1->game_id = $this->game_id;
$model1->con_id = $row;
$model1->save(false);
}
parent::afterSave();
}
you are saving one model over and over
you should change your code like this:
protected function afterSave()
{
$con[]= explode('|', $this->con_id);
foreach($con as $row){
$model1=new GameConsole; // this line creates new GameConsole
$model1->game_id= $this->game_id;
$model1->con_id=$row;
$model1->save(false);
}
return parent::afterSave(); // update : return it
}
and btw why are you not validating?