In my application, I have a categories table, and multiple tables including services and articles that need to be categorised. For convenience, I want to use a polymorphic model for this data.
A category is created to be used by either services or articles. Once a table has been defined as a services table, for example, it is not going to be displayed as a possible category to add articles to.
This also applies to listing. I will have a menu for articles, and a menu for services, and each of these will list just article or service categories, whether they be empty or whether they contain their respective types.
A service category, for example, can be used for many services. Similarly, a service can have many categories - but only service categories.
As it stands, my database is possibly insufficient. I have not used a pivot-table, but when I tried to use one, it didn't allow me to select just article categories or service categories; in fact, it couldn't differ between the two at all.
Basically, I need to be able to:
where('categorizable_type', 'App\Service')
?)where('categorizable_type', 'App\Article')
?)In this ideal situation, I can easily add new (or existing) articles/services to categories, too:
$category = App\Category::find(1);
$article = new App\Article();
$article->title = 'This is an article title.';
$category->articles()->save($article);
And I can easily add new (or existing) categories to articles/services:
$article = App\Article::find(1);
$category = new App\Category();
$category->title = 'This is a category title.';
$article->categories()->save($category);
Well, your database and your model definitions look fine, as well as your code for adding a category to an article. However, your code for adding an article to a category is a little off.
First, there is no $category->articles()
method. To access the related objects, you use your defined relationship: $category->categorizable()
. Also, the relationship attribute, $category->categorizable
will contain the loaded related object, and it will automatically either be an Article
or a Service
object, depending on what is related.
Second, this is the morphTo()
side of the relationship; it behaves like the belongsTo()
, and has similar methods. For example, there is no save()
method, but you have the associate()
method. This means you have to create your article first, and then associate it with the category. Also, associate()
does not automatically save, so you need to call that, as well.
$article = new App\Article();
$article->title = 'This is an article title.';
$article->save();
$category = App\Category::find(1);
$category->categorizable()->associate($article);
$category->save();
// showing use of relationship attribute
$related = $category->categorizable;
echo get_class($related);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With