0

Basically, it would be really nice to delete something and have it automatically search out and delete all of the rows and fields connected to it, rather than having to do all of that manually.

For example, using eager loading, I can eager load like so:

Page::with(array(
    'elements',
    'elements.drafts',
    'elements.content',
    'elements.content.drafts'
))->where('myField', '=', $value)->first();

is there a way to do something similar for the delete operation? Something like:

Page::with(array(
    'elements',
    'elements.drafts',
    'elements.content',
    'elements.content.drafts'
))->where('myField', '=', $value)->delete();

Of course, I've tried the above code and it did not work. I'm providing it to help communicate what I'm looking for.

Pete
  • 7,289
  • 10
  • 39
  • 63

1 Answers1

1

After a bit more searching I was able to figure it out! I'm far frame an SQL expert, so I didn't even know to search for a "CASCADE" delete, which is what it's called in SQL terms.

In any case, I found more information another StackOverflow post.

I ended up having to set up delete function throughout all of my relationships.

For has_many relationships

For has_many relationships I had to use the code from the other StackOverflow post. Specifically, like so:

// This code is in my elements model, which has_many content
public function delete()
{
    foreach($this->content as $content)
    {
        $content->delete();
    }

    return parent::delete();
}

For has_one relationships

I do want to point out, however, that if you are dealing with a has_one relationship, you have to alter your code so that it looks like what is below.

// This is inside my content model, which has_one draft
public function delete()
{
    // delete the single draft
    $this->drafts()->delete();

    return parent::delete();
}
Community
  • 1
  • 1
Pete
  • 7,289
  • 10
  • 39
  • 63
  • Why don't you use MySQL's `ON DELETE CASCADE`? In my opinion using MySQL to delete related rows is a better option... – Adrenaxus Apr 04 '13 at 14:01
  • Interesting--in what respect? And do you mean to specify that in the model? The advantage of this method, it seems, is that once these relationships are set up, everything happens behind the scenes. (i.e. in my example, any time I do a `Page::find(1)->delete();` it will automatically delete all connected resources--since the relationships have been set up that way.) – Pete Apr 04 '13 at 17:16
  • You're basically right, it's nice if your relationships are being deleted automatically. But: _who_ will delete them? In your case, **Laravel** takes care of your relations, but what if you need to manually delete a row from your DB? (for example if your site is temporarily offline) What if you move your project to another framework? You will then need to delete related models manually and or rewrite code (DRY, remember? also: hello orphans). So why not outsource as much logic as possible to your database for some extra independece? – Adrenaxus Apr 05 '13 at 07:10
  • Very interesting thoughts! So, would you say that you are not a big fan, in general, of taking advantage of ActiveRecord implementations? Or just in the case of `CASCADE` deletes? – Pete Apr 05 '13 at 17:26
  • I like ActiveRecord, no reason to dislike it. Basically what I'm trying to do is taking advantage of what MySQL offers, and `ON UPDATE` and `ON DELETE` are generally very useful, plus they help to maintain [referential integrity](http://en.wikipedia.org/wiki/Referential_integrity) - for example by not being able to delete a row that is being referenced by another table. (`ON DELETE RESTRICT`). – Adrenaxus Apr 05 '13 at 23:09