簡體   English   中英

Laravel在Eloquent mutators中保存了多對多的關系

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

我有兩個具有多對多關系的模型。 我希望能夠使用一組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');
    }

}

但是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。

看起來你正在調用函數不正確或從未初始化的模型調用。 該錯誤表明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()在你的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