我有 2 个具有多对多关系的模型。我希望能够使用id数组设置特定属性,并在突变器中建立这样的关系:
<?php
class Profile extends Eloquent {
protected $fillable = [ 'name', 'photo', 'tags' ];
protected $appends = [ 'tags' ];
public function getTagsAttribute()
{
$tag_ids = [];
$tags = $this->tags()->get([ 'tag_id' ]);
foreach ($tags as $tag) {
$tag_ids[] = $tag->tag_id;
}
return $tag_ids;
}
public function setTagsAttribute($tag_ids)
{
foreach ($tag_ids as $tag_id) {
$this->tags()->attach($tag_id);
}
}
public function tags()
{
return $this->belongsToMany('Tag');
}
}
<?php
class Tag extends Eloquent {
protected $fillable = [ 'title' ];
protected $appends = [ 'profiles' ];
public function getProfilesAttribute()
{
$profile_ids = [];
$profiles = $this->profiles()->get([ 'profile_id' ]);
foreach ($profiles as $profile) {
$profile_ids[] = $profile->profile_id;
}
return $profile_ids;
}
public function profiles()
{
return $this->belongsToMany('Profile');
}
}
但是,setTagsAttribute
函数未按预期工作。我收到以下错误:SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'profile_id' cannot be null (SQL: insert into
profile_tag (
profile_id ,
tag_id ) values (?, ?)) (Bindings: array ( 0 => NULL, 1 => 1, ))
在
保存模型之前,无法附加多对多关系。在设置$model->tags
之前调用模型上的save()
,您应该没问题。这样做的原因是模型需要有一个 Laravel可以放入数据透视表中的 ID,该 ID 需要两个模型的 ID。
看起来您调用了不正确的函数或从未初始化的模型中调用了该函数。错误指出profile_id为 NULL。因此,如果要按$profile->setTagsAttribute()
调用函数,则需要确保使用 ID 在数据库中初始化$profile。
$profile = new Profile;
//will fail because $profile->id is NULL
//INSERT: profile->save() or Profile::Create();
$profile->setTagsAttribute(array(1,2,3));
此外,您可以将数组传递给 attach 函数以一次附加多个模型,如下所示:
$this->tags()->attach($tag_ids);
您也可以将模型而不是ID传递给它(但可以肯定的是,模型数组不起作用(
尝试使用同步方法:
class Profile extends Eloquent {
protected $fillable = [ 'name', 'photo', 'tags' ];
protected $appends = [ 'tags' ];
public function getTagsAttribute()
{
return $this->tags()->lists('tag_id');
}
public function setTagsAttribute($tag_ids)
{
$this->tags()->sync($tagIds, false);
// false tells sync not to remove tags whose id's you don't pass.
// remove it all together if that is desired.
}
public function tags()
{
return $this->belongsToMany('Tag');
}
}
不要通过 tags()
函数访问标记,而是使用 tags
属性。如果要将其他参数弹出到关系查询上,请使用函数名称,如果只想获取标记,请使用属性。 tags()
在您的吸气器中起作用,因为您最后使用的是get()
。
public function setTagsAttribute($tagIds)
{
foreach ($tagIds as $tagId)
{
$this->tags->attach($tagId);
}
}