Laravel polymorph关系查询查找错误的列

时间:2016-08-03 12:36:04

标签: php laravel eloquent polymorphism laravel-5.2

我正在尝试创建我的第一个多态关系,并且已经按照网站上的文档进行了检查,并在线查看了几个类似主题的教程。我有3个表,页面,菜单和菜单项。菜单项始终是菜单的子项,并且可以是页面(在链接的情况下)或其他菜单(在子菜单的情况下)。我的表是:

信息页

+----+------+----------+------+--------+-----------+-----------------+------------+------------+------------+
| id | name | url_slug | file | layout | seo_title | seo_description | created_at | updated_at | deleted_at |
+----+------+----------+------+--------+-----------+-----------------+------------+------------+------------+

菜单

+----+------+------------+------------+
| id | name | created_at | updated_at |
+----+------+------------+------------+

菜单项

+----+---------+-------------+---------------+-------+------+-------+------------+------------+
| id | menu_id | itemable_id | itemable_type | label | left | right | created_at | updated_at |
+----+---------+-------------+---------------+-------+------+-------+------------+------------+

因此,对于菜单项表,menu_id是菜单项的父项,它与菜单表有一对多的关系。 itemable_iditemable_type用于多态关系,itemable_id应引用菜单或页面中的id列,具体取决于itemable_type是什么,这将是菜单或页面模型。

为了建立这种关系,我已经为我的模型添加了这样的方法:

网页

/**
 * Fetch the menu items this page is linked to.
 *
 * @return \Illuminate\Database\Eloquent\Relations\MorphMany
 */
public function menuItems()
{
    return $this->morphMany('App\Modules\Menu\Models\MenuItem', 'itemable');
}

菜单

/**
 * Fetch all child menu items belonging to this menu.
 *
 * @return \Illuminate\Database\Eloquent\Relations\HasMany
 */
public function childItems()
{
    return $this->hasMany('App\Modules\Menu\Models\MenuItem');
}

/**
 * Fetch all menu items linked to this menu.
 *
 * @return \Illuminate\Database\Eloquent\Relations\MorphMany
 */
public function menuItems()
{
    return $this->morphMany('App\Modules\Menu\Models\MenuItem', 'itemable');
}

菜单项

/**
 * Fetch the menu this item belongs to.
 *
 * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
 */
public function menu()
{
    return $this->belongsTo('App\Modules\Menu\Models\Menu');
}

/**
 * Fetch the models this menu item links to.
 *
 * @return \Illuminate\Database\Eloquent\Relations\MorphTo
 */
public function itemable()
{
    return $this->morphTo();
}

我已经创建了所有表格,而我现在正试图为它们播种。我的种子看起来像这样:

public function run()
{
    $menu = Menu::create([
        'name' => 'Main'
    ]);

    foreach ( [
                  [
                      'page_id' => 1,
                      'label' => 'Home',
                      'left' => 1,
                      'right' => 2
                  ],
                  [
                      'page_id' => 2,
                      'label' => 'About Us',
                      'left' => 3,
                      'right' => 4
                  ]
              ] as $arr )
    {
        /* @var $page Page */
        $page = Page::findOrFail($arr['page_id']);
        $item = new MenuItem($arr);
        $page->menuItems()->save($item);
        $item->menu()->associate($menu);
    }
}

但是当我运行page_id列时,我一直遇到错误。确切的错误是

[Illuminate\Database\QueryException]                                                                                                                                                                                                                              
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'page_id' in 'field list' (SQL: insert into `menu_items` (`page_id`, `label`, `left`, `right`, `itemable_type`, `itemable_id`, `updated_at`, `created_at`) values (1, Home, 1, 2, App\Models\Page, 1, 2016-08-03 12:32:21, 2016-08-03 12:32:21)) 

关于查询的一切都很好,除了它试图填充page_id以及可迭代列。它为什么这样做?我怎么能绕过它?

2 个答案:

答案 0 :(得分:2)

尝试将page_id更改为itemable_id

[
  'page_id' => 1, //change this to itemable_id
  'label' => 'Home',
  'left' => 1,
  'right' => 2
],
[
  'page_id' => 2, //change this to itemable_id
  'label' => 'About Us',
  'left' => 3,
  'right' => 4
]

因为在以下行中,

$item = new MenuItem($arr);

当您尝试在MenuItem中插入$arr时,它期待itemable_id而不是page_id
所以你更新的代码是这样的:

public function run()
{
    $menu = Menu::create([
        'name' => 'Main'
    ]);

    foreach ( [
                  [
                      'itemable_id' => 1,
                      'label' => 'Home',
                      'left' => 1,
                      'right' => 2
                  ],
                  [
                      'itemable_id' => 2,
                      'label' => 'About Us',
                      'left' => 3,
                      'right' => 4
                  ]
              ] as $arr )
    {
        /* @var $page Page */
        $page = Page::findOrFail($arr['itemable_id']);
        $item = new MenuItem($arr);
        $page->menuItems()->save($item);
        $item->menu()->associate($menu);
    }
}

答案 1 :(得分:0)

您的menu_items列不包含任何page_id列,当您尝试为您种子时,尝试将新数据存储到{ {1}}并且它会检查menu_items中的每个列与目的地表file_list并且包含

菜单项

menu_items

因此,将列重命名为+----+---------+-------------+---------------+-------+------+-------+------------+------------+ | id | menu_id | itemable_id | itemable_type | label | left | right | created_at | updated_at | +----+---------+-------------+---------------+-------+------+-------+------------+-- ,如此

itemable_id