简体   繁体   English

Laravel在Eloquent mutators中保存了多对多的关系

[英]Laravel save many-to-many relationship in Eloquent mutators

I've got 2 models with a many-to-many relationship. 我有两个具有多对多关系的模型。 I want to be able to set a specific attribute with an array of ids and make the relationship in the mutator like this: 我希望能够使用一组id设置一个特定的属性,并在mutator中建立这样的关系:

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

}

However the setTagsAttribute function isn't working as expected. 但是setTagsAttribute函数没有按预期工作。 I'm getting the following error: 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, )) 我收到以下错误: 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, ))

You can't attach many-to-many relations until you've saved the model. 在保存模型之前,不能附加多对多关系。 Call save() on the model before setting $model->tags and you should be OK. 在设置$model->tags之前在模型上调用save() ,你应该没问题。 The reason for this is that the model needs to have an ID that Laravel can put in the pivot table, which needs the ID of both models. 原因是模型需要具有Laravel可以放入数据透视表的ID,这需要两个模型的ID。

It looks like you're calling the function incorrectly or from an uninitialized model. 看起来你正在调用函数不正确或从未初始化的模型调用。 The error says that profile_id is NULL. 该错误表明profile_id为NULL。 So if you're calling the function as $profile->setTagsAttribute() you need to make sure that $profile is initialized in the database with an ID. 因此,如果您将函数调用为$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));  

Additionally, you can pass an array to the attach function to attach multiple models at once, like so: 此外,您可以将数组传递给attach函数以一次附加多个模型,如下所示:

$this->tags()->attach($tag_ids);

You can also pass it the model instead of the ID (but pretty sure array of models won't work) 您也可以传递模型而不是ID(但很可靠的模型数组不起作用)

Try using the sync method: 尝试使用同步方法:

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

}

Don't access the tags through the tags() function, rather use the tags property. 不要通过tags()函数访问标记,而是使用tags属性。 Use the function name if you want to pop additional parameters onto the relationship query and the property if you just want to grab the tags. 如果要在关系查询和属性上弹出其他参数(如果只想抓取标记),请使用函数名称。 tags() works in your getter because you're using get() on the end. tags()在你的getter中工作,因为你最后使用了get()

public function setTagsAttribute($tagIds)
{
    foreach ($tagIds as $tagId)
    {
        $this->tags->attach($tagId);
    }
}

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

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