【问题标题】:Laravel morph relationshipLaravel 变形关系
【发布时间】:2017-04-10 13:49:44
【问题描述】:

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

一家商店有很多产品,一个产品可以是“商品”、“活动”或“服务”。

我有以下表格:

  • 商店
    • 身份证
    • user_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)'

有人知道这是哪里出了问题吗?我可能误解了这种类型的关系......

【问题讨论】:

  • 试试$shop->products()->create($event);
  • @Sherif 也不起作用。我得到:TypeError: Argument 1 passed to Illuminate\Database\Eloquent\Relations\HasOneOrMany::create() 必须是数组类型,对象给定在第 3 行
  • 对不起,我们没有在这里创建。一个事件属于一个产品,所以这个语法是错误的
  • 你需要指定某个产品然后$product->create($event);
  • 不确定

标签: php sql laravel eloquent polymorphism


【解决方案1】:

首先添加一个从ProductShop的反向关系Model

    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
  ]);
}

如果有问题,请在下面的 cmets 中告诉我 :)

-- 编辑

首先,请理解您不能从hasMany() 关系向productable_idproductable_type 添加条目。您需要确保使用 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]);

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

【讨论】:

  • 我真的不想创建一个空事件。我只是懒得写出属性.. :) 当我尝试您的解决方案时,我收到此错误:Illuminate\Database\QueryException with message 'SQLSTATE[23000]: Integrity constraint violation: 19 NOT NULL constraint failed: products.productable_id (SQL:插入“products”(“shop_id”、“updated_at”、“created_at”)值(1、2016-11-28 08:51:24、2016-11-28 08:51:24))'我尝试像这样保存它: $shop = Shop::first() $product = new Product $product->productable()->save(Event::create([])) $shop->products()->保存($产品)
  • @Bisgaard 您能否编辑您的问题并对其进行更改,以便我知道您到底在尝试什么?另外,请不要使用$product = new Product;,而是使用$product = Product::create([]);。编辑完问题后告诉我。
  • @prateekkathal 为什么 - “请不要做 $product = new Product;而是做 $product = Product::create([]);” ?
  • @cja 根据用例,如果您只想在 PHP 内存中创建项目,则可以使用 new Model(),否则,将其创建到数据库中并使用关系查询,您必须改为 Model::create
猜你喜欢
  • 2018-10-16
  • 1970-01-01
  • 1970-01-01
  • 2023-03-14
  • 2021-06-24
  • 1970-01-01
  • 2021-07-24
  • 2019-04-27
  • 2018-10-03
相关资源
最近更新 更多