繁体   English   中英

Laravel 5.5 Pivot多对多保存一次

[英]Laravel 5.5 pivot many-to-many saves only once

我的多对多关系为每个项目仅保存一次数据,我找不到将多个属性附加到多个项目时可能犯的错误。

这是我的模型:

项目

<?php
    ...
    class Item extends Model
    {

        protected $fillable = [
            'external_id',
            'url',
            'created_at',
            'updated_at'
        ];

        /**
        * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
        */
        public function attributes()
        {

            return $this->belongsToMany(AttributeValue::class);
        }

    }

属性

<?php
    ...
    class Attribute extends Model
    {

        protected $fillable = [
            'name'
        ];

        /**
        * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
        */
        public function values()
        {

            return $this->belongsToMany(AttributeValue::class);
        }

    }

的AttributeValue

<?php
    ...
    class AttributeValue extends Model
    {

        protected $fillable = [
            'attribute_id',
            'name',
        ];

        /**
        * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
        */
        public function items()
        {

            return $this->belongsToMany(Item::class);
        }


        /**
        * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
        */
        public function attribute()
        {

            return $this->belongsTo(Attribute::class);
        }

    }

如您所见,我尝试将属性及其值分开以更好地访问$item->attributes()$attribute->values()类的每个值。

我的迁移如下所示:

项目

<?php
   ...
   class CreateItemsTable extends Migration
   {

       public function up()
       {
            Schema::create('items', function ( Blueprint $table ) {
                $table->increments('id');
                $table->string('external_id');
                $table->string('url');
                $table->timestamps();
       }
   }

属性

<?php
   ...
   class CreateAttributesTable extends Migration
   {

       public function up()
       {
            Schema::create('attributes', function ( Blueprint $table ) {
                $table->increments('id');
                $table->string('name');
                $table->timestamps();
       }
   }

属性值

<?php
   ...
   class CreateAttributeValuesTable extends Migration
   {

       public function up()
       {
            Schema::create('attribute_values', function ( Blueprint $table ) {
                $table->increments('id');
                $table->text('name');
                $table->integer('attribute_id')->unsigned();
                $table->foreign('attribute_id')->references('id')->on('attributes')->onDelete('cascade');
                $table->timestamps();
       }
   }

...最后但并非最不重要的一点是,由Jeffrey Way的出色Laravel Extended Generators创建的数据透视表

属性值项枢纽

<?php
   ...
   class CreateAttributeValueItemPivotTable extends Migration
   {

       public function up()
       {
            Schema::create('attribute_value_item', function ( Blueprint $table ) {
                $table->integer('attribute_value_id')->unsigned()->index();
                $table->foreign('attribute_value_id')->references('id')->on('attribute_values')->onDelete('cascade');

                $table->integer('item_id')->unsigned()->index();
                $table->foreign('item_id')->references('id')->on('items')->onDelete('cascade');

                $table->primary([ 'attribute_value_id', 'item_id' ]);
    });
       }
   }

我知道,这是很多代码,但是我认为这是帮助我解决此问题的必要条件。

想象一下,我正在获取具有诸如品牌,大小,高度等属性的不同项目的对象。

当我尝试将它们附加到我的数据透视表时

$items = $this->getExternalItemsObject();

...

foreach($items as $item) {

    $attributes = $item->Attributes->AttributesValueList;

    foreach ( $attributes as $attribute )
    {        

        $itemAttribute = Attribute::firstOrCreate([ 'name' => $attribute->Name ]);

        $itemAttributeValue = AttributeValue::firstOrCreate(
            [ 'name' => $attribute->Value[0] ],
            [ 'attribute_id' => $itemAttribute->id ]
        );

        $itemAttributeValue->items()->attach($item->id);
    }

现在,当遍历第一项时,一切正常。 所有属性ID均与相关项目ID一起存储在数据透视表中。 但是对于第二,第三,第n项,有时具有与品牌相同的属性(比如耐克或类似的东西),则关系被跳过并且不保存。

这真的是古玩,老实说,让我有点疯狂。

好吧,看来我没有遵循正确的约定来命名数据透视表。

因此,添加第二个参数belongsToMany()方法即可解决该问题。

这是它的外观:

...

return $this->belongsToMany(AttributeValue::class, 'attribute_value_item');

...

...对于相关的多对多模型也是如此。

另外,我不得不使用->syncWithoutDetaching([$item->id])而不是->attach($item->id)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM