【问题标题】:Laravel 5.5 pivot many-to-many saves only onceLaravel 5.5 pivot 多对多只保存一次
【发布时间】:2017-10-30 06:55:16
【问题描述】:

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

这是我的模型:

物品

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

    }

属性值

<?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-&gt;attributes()$attribute-&gt;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 个项目,例如品牌(比如耐​​克或类似的东西),关系被跳过并且没有被保存。

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

【问题讨论】:

    标签: php mysql laravel eloquent pivot


    【解决方案1】:

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

    所以添加第二个参数belongsToMany()method 解决了它。

    这就是它的样子:

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

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

    此外,我必须使用-&gt;syncWithoutDetaching([$item-&gt;id]) 而不是-&gt;attach($item-&gt;id)

    【讨论】:

      猜你喜欢
      • 2015-12-23
      • 2021-11-29
      • 2018-03-16
      • 2015-09-06
      • 1970-01-01
      • 2018-08-13
      • 2021-01-13
      • 2020-02-29
      • 2015-03-05
      相关资源
      最近更新 更多