我建议在这里使用多态 many-to-many 方法,以便 icons 可重复使用并且不需要一堆数据透视表,如果您希望 icons 在页面以外的其他内容上。
Schema::create('icons', function(Blueprint $table) {
$table->increments('id');
$table->string('name');
});
Schema::create('iconables', function(Blueprint $table) {
$table->integer('icon_id');
$table->integer('iconables_id');
$table->integer('iconables_type');
});
现在您只需要确定页面是否有现有的Icon。如果有,请保留对它们的引用,以便您可以插入它们:
$pagesWithIcons = Page::whereNotNull('icon')->get();
此时您需要在模型中定义多态关系:
// icon
class Icon extends Model
{
public function pages()
{
return $this->morphedByMany(Page::class, 'iconable');
}
}
// page
class Page extends Model
{
public function pages()
{
return $this->morphToMany(Icon::class, 'iconable');
}
}
现在您只需要创建icons(回到我们的迁移中),然后在它们存在时附加它们:
$pagesWithIcons->each(function(Page $page) {
$icon = Icon::firstOrNew([
'name' => $page->icon
});
$icon->pages()->attach($page);
});
上面是创建一个Icon 如果它不存在,或者如果它存在则查询它。然后将页面附加到icon。由于多态 many-to-many 关系只是在底层使用 belongsToMany() 方法,如果这不符合您的需求,您可以在闲暇时使用所有可用的操作。
最后,从页面中删除您的 icons 列,您不需要它。
Schema::table('pages', function(Blueprint $table) {
$table->dropColumn('icon');
});
如果您只需要回填对单个 icon 的支持(因为 many-to-many 现在将返回一个数组关系),您可以将以下内容添加到您的 page 模型中:
public function icon()
{
return $this->icons()->first();
}
抱歉,如有错别字,我是在手机上做的,所以可能有一些错误。