I've been reading the Laravel-Mediable docs about deleting media.
However, I'm a bit confused on how to delete a specific media, together with its file without using query builder. As per the docs,
Note: The delete() method on the query builder will not delete the associated file. It will still purge relationships due to the cascading foreign key.
Author of laravel-mediable here.
The reason for this is that when a mediable model's delete() method is called, we are able to hook into that behaviour to clean up the file from the disk. However, when the delete() method of the query builder is called, it simply runs a DELETE FROM ... SQL query on the database without notifying any other part of the application.
The easiest way to delete models matching a query along with their files is to perform a select query first, then delete the models one by one.
$results = Media::where(...)->get();
$results->each(function($media) {
$media->delete();
});
Granted, that results in N+1 queries. I will make note to add a better mass deletion method to the todo list for the next version.
Related
I received an update of a Phalcon model class and I had to update my local data table with the new attributes the model contains. Usually this kind of operation is not a problem, I simply launch an alter SQL query on the to add the columns, assign values to the object, call save and that's it.
However this time something strange happened: when I call save() on the model, everything is updated/created except the two new attributes I've added in my table. I checked the logs to take a look at the raw SQL query and the two new attributes are missing, the funny thing is that this operation worked the first times I tested it.
I think this error might come from the framework, after debugging my code I see clearly that the model takes the new values but for some reason cannot pass it to the SQL query.
Thus my question is the following: is there a way to force the Phalcon model to be sync again with my table?
I have 4 tables. Two of them are monomorphic and two of them are polymorphic.
Monomorphic:
Templates, Modules
Polymorphic:
Documents, Images
Now, templates and modules have both documents and images and each Template has many Modules and modules have foreign key that is set to cascade on deletion of templates.
Now, if I delete a Template the associated Modules will be deleted but the associated polymorphic relations of Module will stay in Database. I haven't tried anything because I am completely clueless.
Anything I could do to automatically delete associations of Module when Template is deleted? I think the deletion here in this is being handled by Database itself and Eloquent doesn't have anything to do with it.
Because it is a polymorphic relationship, the cascading delete cannot be handled by a foreign key.
If you still want the deletes to be handled at the database level, you will need to write some type of database trigger functionality.
There are also a couple options if you want to handle this at the application level.
One option is to update your code so that everywhere you delete your Template, you also make sure to delete all of it's polymorphic relations.
Another option would be to create an event handler for the deleting event. The deleting event is fired by Eloquent whenever you delete an Eloquent model. Inside this deleting event, you can access the polymorphic relationship and delete them, as well.
If the deleting event method sounds okay, there is a package that implements all of this for you, and makes it very easy to setup for your models: shiftonelabs/laravel-cascade-deletes. Full disclosure: I wrote the package.
With this package, you just add the CascadesDeletes trait to your Template model, and then add a $cascadeDeletes property that contains an array of all the relationships to delete when a Template instance is deleted.
It's not fully automatic, but I handle it very easy with the destroy() Eloquent method. https://laravel.com/docs/8.x/eloquent#deleting-an-existing-model-by-key In addition, when you will use it with Laravel Queues, it works like a charm...
Example:
$template = Template::find(1);
Module::destroy($template->modules);
$template->delete();
You can actually use delete method on both types of relationship:
$template = Template::find(1);
$template->modules()->delete();
$template->images()->delete();
$template->delete();
Key note here is that $template->modules returns a collection instance while $template->modules() return an eloquent relationship where you can chain delete() method.
I need some help dealing with a relational table that is an entity due to the existence of an additional property.
Here is a gist of the entities in question: https://gist.github.com/chasepeeler/efd7efd890c58eafb81f
Do I have something configured wrong that is forcing me to do the flush in controller.php line 15?
I've also tried just updating the rank attribute of the queueItem record in the Queue::queueItems collection, but when I do that, it doesn't even save the changes to the database.
$queueItems->clear() does the same thing as clearQueueItems, but one time.
And if you want to override current queue state, you should just implement and call setQueueItems(ArrayCollection $queueItemList) method.
UnitOfWork will compute your changes to insert and remove new/deleted items.
Every OneToMany annotated field should implement setItems, addItem and removeItem methods, where Item is related entity name.
Your sortQueue method shouldn't persist and commit changes into database.
It should only return a sorted Collection.
Maybe I didn't get that, it's hard to say what you want to achieve, controller's code says me nothing.
So I have a lot of controllers that will be created by one user. So on every save/create/update I want the user's ID to be saved the resource's user_id column in the database.
I know that before the actual database update I could go like
$resource->user_id = Auth::user()->id;
but this seems pretty unclean and I don't wanna do this for all the create/update actions I have spread across multiple controllers.
What would be the best and cleanest way to approach this issue?
If you are using Eloquent ORM to define $resource you can define Events for that model, that will be executed (if you wish) after or before every create, update, save, delete or restore action on that model. You can see the documentation here: Laravel 5.1 Model Events Documentation
Create a trait that hooks into the model’s saving event, and set the user ID there.
I'm in the process of trying to create a logging interface for our application. I need to track when a change happens in the database through the application. So when someone updates a field I need to insert a row into the log with the table, columns original value, columns new value, timestamp, and user that made change. To me the logical way of doing this is to tie into the DB class in laravel so everytime it's called and an update / delete method is used it runs my new method of getting the needed info and inserting it in the log.
I need it to work at the DB level I believe as it needs to happen for updates / deletes called from DB or eloquent.
How would I go about doing this?
Eloquent provides you with some nice events, they're even in the docs ! Who knew you can find so much in there.
http://laravel.com/docs/eloquent#model-events
Instead of trying to attach something onto the DB layer, have you considered using Model Observers (http://laravel.com/docs/eloquent#model-observers) to watch all update and delete events and put your logic in that observer?
Upon searching and trial and error I accomplished my goal the following way.
I created an Event listener that I for organizational purposes placed in /app/events/database.php
With the following
<?php
Event::listen('illuminate.query', function($query, $bindings, $time, $name)
{
// Code to log query goes here
});
I then placed in my /app/start/global.php the following line
include(app_path().'/events/database.php');
This now captures all requests to query the database using either DB, or Eloquent.