[英]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.