Laravel变形关系

时间:2016-11-26 10:13:35

标签: php sql laravel eloquent polymorphism

我有一个关于在Laravel中保存多态关系的问题。这是我想在laravel中创建的模型。

Class diagram

商店有很多产品,产品可以是“项目”,“活动”或“服务”。

我有以下表格:

  • 商店
    • ID
    • USER_ID
    • 名称
  • 事件
    • ID
    • 公共
    • 标题
    • 描述
  • 产品
    • ID
    • shop_id
    • productable_id
    • productable_type

这就是我设置模型的方式:

class Shop extends Model{
    public function products(){
        return $this->hasMany('App\Product');
    }
}

class Product extends Model{
    public function productable(){
        return $this->morphTo();   
    }
}

class Event extends Model{
    public function product(){
        return $this->morphOne('App\Product','productable');
    }
}

我希望能够做到以下几点:

$shop = Shop::first()
$event = Event::create(['title'=>'Some event']);
$service = Service::create(['title' => 'Some service']);
$shop->products()->save($event);
$shop->products()->save($service);

但它不起作用!当我试图保存我得到的关系:

Illuminate\Database\QueryException with message 'SQLSTATE[HY000]: General error: 1 no such column: shop_id (SQL: update "accendo_events" set "updated_at" = 2016-11-26 10:11:02, "shop_id" = 1 where "id" = 1)'

任何人都知道这出错的地方?我可能误解了这种关系......

1 个答案:

答案 0 :(得分:5)

首先从Shop 模型

添加Product的背面关系
class Shop extends Model
{
  public function products()
  {
    return $this->hasMany('App\Product');
  }
}

class Product extends Model
{
  public function shop()
  {
    return $this->belongsTo('App\Shop');
  }

  public function productable()
  {
    return $this->morphTo();
  }
}

class Event extends Model
{
  public function product()
  {
    return $this->morphOne('App\Product', 'productable');
  }
}

现在,我不确定您为什么要尝试制作一个空白的事件并将其添加到所有产品中,但如果您想针对任何用例进行此操作...请按照以下方法进行...: )

$shop = Shop::first();            //or $shop = Shop::find(1);

foreach($shop->products as $product) {
  $event = Event::create([]);
  $service = Service::create([]);

  $product->productable()->saveMany([
    $event, $service
  ]);
}

如果出现问题,请在下面的评论中告诉我们:)

- 编辑

首先,请理解您无法从productable_id关系向productable_typehasMany()添加条目。您需要确保为此目的使用morph关系。

其次,由于您首先尝试添加产品而不是首先添加事件,因此插入方法不适合您。请注意,您必须先尝试创建事件或服务,然后尝试与商店建立关联。

最简单的方法是

$shop = Shop::first();

$event = Event::create(['title' => 'Some Event']);
$event->product()->create(['shop_id' => $shop->id]);

$service = Service::create(['title' => 'Some Service']);
$service->product()->create(['shop_id' => $shop->id]);

你也可以尝试按照我的第一种方法,但我刚才提到的那种方法肯定是可行的......实际上就是它的插入/创建方式。