使用 Eloquent 多态关系对 Laravel 中的数据进行分类
Using Eloquent polymorphic relationships to categorise data in Laravel
在我的应用程序中,我有一个类别 table 和多个 table,包括需要分类的服务和文章。为了方便起见,我想为这个数据使用多态模型。
已创建一个类别以供服务或文章使用。例如,一旦 table 被定义为服务 table,它就不会显示为可以添加文章的类别。
这也适用于列表。我将有一个文章菜单和一个服务菜单,每一个都将只列出文章或服务类别,无论它们是空的还是包含它们各自的类型。
例如,一个服务类别可以用于许多服务。同样,一项服务可以有很多类别 - 但只有服务类别。
目前看来,我的数据库可能不够用。我没有使用 pivot-table,但是当我尝试使用它时,它不允许我 select 只是文章类别或服务类别;事实上,两者之间根本没有区别。
基本上,我需要能够:
- 获取服务可用的所有类别的列表(可能
where('categorizable_type', 'App\Service')
?)
- 获取文章可用的所有类别的列表(可能
where('categorizable_type', 'App\Article')
?)
- 获取一个类别articles/services中所有
的列表
- 获取 article/service
使用的所有类别的列表
在这种理想情况下,我也可以轻松地向类别添加新的(或现有的)articles/services:
$category = App\Category::find(1);
$article = new App\Article();
$article->title = 'This is an article title.';
$category->articles()->save($article);
而且我可以轻松地将新的(或现有的)类别添加到 articles/services:
$article = App\Article::find(1);
$category = new App\Category();
$category->title = 'This is a category title.';
$article->categories()->save($category);
好吧,您的数据库和模型定义看起来不错,还有用于向文章添加类别的代码。但是,您将文章添加到类别的代码有点不对。
首先,没有$category->articles()
方法。要访问相关对象,您可以使用定义的关系:$category->categorizable()
。此外,关系属性 $category->categorizable
将包含加载的相关对象,它会自动成为 Article
或 Service
对象,具体取决于相关内容。
其次,这是关系的morphTo()
方;它的行为类似于 belongsTo()
,并且具有相似的方法。例如,没有 save()
方法,但您有 associate()
方法。这意味着您必须先创建文章,然后将其与类别相关联。此外,associate()
不会自动保存,因此您也需要调用它。
$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);
在我的应用程序中,我有一个类别 table 和多个 table,包括需要分类的服务和文章。为了方便起见,我想为这个数据使用多态模型。
已创建一个类别以供服务或文章使用。例如,一旦 table 被定义为服务 table,它就不会显示为可以添加文章的类别。
这也适用于列表。我将有一个文章菜单和一个服务菜单,每一个都将只列出文章或服务类别,无论它们是空的还是包含它们各自的类型。
例如,一个服务类别可以用于许多服务。同样,一项服务可以有很多类别 - 但只有服务类别。
目前看来,我的数据库可能不够用。我没有使用 pivot-table,但是当我尝试使用它时,它不允许我 select 只是文章类别或服务类别;事实上,两者之间根本没有区别。
基本上,我需要能够:
- 获取服务可用的所有类别的列表(可能
where('categorizable_type', 'App\Service')
?) - 获取文章可用的所有类别的列表(可能
where('categorizable_type', 'App\Article')
?) - 获取一个类别articles/services中所有 的列表
- 获取 article/service 使用的所有类别的列表
在这种理想情况下,我也可以轻松地向类别添加新的(或现有的)articles/services:
$category = App\Category::find(1);
$article = new App\Article();
$article->title = 'This is an article title.';
$category->articles()->save($article);
而且我可以轻松地将新的(或现有的)类别添加到 articles/services:
$article = App\Article::find(1);
$category = new App\Category();
$category->title = 'This is a category title.';
$article->categories()->save($category);
好吧,您的数据库和模型定义看起来不错,还有用于向文章添加类别的代码。但是,您将文章添加到类别的代码有点不对。
首先,没有$category->articles()
方法。要访问相关对象,您可以使用定义的关系:$category->categorizable()
。此外,关系属性 $category->categorizable
将包含加载的相关对象,它会自动成为 Article
或 Service
对象,具体取决于相关内容。
其次,这是关系的morphTo()
方;它的行为类似于 belongsTo()
,并且具有相似的方法。例如,没有 save()
方法,但您有 associate()
方法。这意味着您必须先创建文章,然后将其与类别相关联。此外,associate()
不会自动保存,因此您也需要调用它。
$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);