【发布时间】: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->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 个项目,例如品牌(比如耐克或类似的东西),关系被跳过并且没有被保存。
这真的是古玩,老实说让我有点发疯。
【问题讨论】:
标签: php mysql laravel eloquent pivot