同一模型上的 Laravel ManyToMany 关系

Man*_*anu 6 php mysql relationship laravel eloquent

我试图在我的标签模型上建立双向多对多关系,但我遇到了这个“问题”。

我的模型如下所示:


<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Tag extends Model
{
    protected $table = 'tags';
    public $timestamps = false;

    public function tags()
    {
        return $this->belongsToMany(Tag::class, 'tag_tag', 'tag_one_id', 'tag_two_id');
    }

}

Run Code Online (Sandbox Code Playgroud)

现在假设我的标签表中有 Tag1 和 Tag2,然后我将 Tag2 与 Tag1 关联起来。现在我的数据透视表将如下所示:

+----+------------+------------+
| id | tag_one_id | tag_two_id |
+----+------------+------------+
| 1  | 1          | 2          |
+----+------------+------------+
Run Code Online (Sandbox Code Playgroud)

当我尝试这段代码时:

$tag = Tag::find(1);
$tag->tags()->get();
Run Code Online (Sandbox Code Playgroud)

我得到了 Tag2 实例,它是正确的。

但是当我尝试运行这段代码时:

$tag = Tag::find(2);
$tag->tags()->get();
Run Code Online (Sandbox Code Playgroud)

我想接收 Tag1 实例,但我没有。

是否可以仅使用模型上的一种方法使用 Laravel 默认 Eloquent 来完成此任务?

Man*_*anu 8

我找到了一个解决方案,然后我就这样解决了。

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Tag extends Model
{
    /**
     * @inheritdoc
     *
     * @var string
     */
    protected $table = 'tags';

    /**
     * @inheritdoc
     *
     * @var bool
     */
    public $timestamps = false;

    /*
    |--------------------------------------------------------------------------
    | RELATIONS
    |--------------------------------------------------------------------------
    */

    /**
     * Every tag can contain many related tags (TagOne has many TagTwo).
     *
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
     */
    protected function tagsOneTwo()
    {
        return $this->belongsToMany(Tag::class, 'tag_tag', 'tag_one_id', 'tag_two_id');
    }

    /**
     * Every tag can contain many related tags (TagTwo has many TagOne).
     *
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
     */
    protected function tagsTwoOne()
    {
        return $this->belongsToMany(Tag::class, 'tag_tag', 'tag_two_id', 'tag_one_id');
    }

    /**
     * This method returns a collection with all the tags related with this tag.
     * It is not a real relation, but emulates it.
     *
     * @return \Illuminate\Database\Eloquent\Collection
     */
    public function tags()
    {
        return $this->tagsOneTwo()->get()->merge($this->tagsTwoOne()->get())->unique('id');
    }

    /*
    |--------------------------------------------------------------------------
    | FUNCTIONS
    |--------------------------------------------------------------------------
    */

    /**
     * Function to relate two tags together.
     *
     * @param Tag $tag
     * @return void;
     */
    public function attach(Tag $tag)
    {
        if ($this->tags()->contains('id', $tag->getKey())) {
            return;
        }

        $this->tagsOneTwo()->attach($tag->getKey());
    }

    /**
     * Function to un-relate two tags.
     *
     * @param Tag $tag
     * @return void;
     */
    public function detach(Tag $tag)
    {
        if ($this->tags()->contains('id', $tag->getKey())) {
            // Detach the relationship in both ways.
            $this->tagsOneTwo()->detach($tag->getKey());
            $this->tagsTwoOne()->detach($tag->getKey());
        }
    }

    /*
    |--------------------------------------------------------------------------
    | ACCESORS
    |--------------------------------------------------------------------------
    */

    /**
     * Let access the related tags like if it was preloaded ($tag->tags).
     *
     * @return mixed
     */
    public function getTagsAttribute()
    {
        if (! array_key_exists('tags', $this->relations)) {
            $this->setRelation('tags', $this->tags());
        };

        return $this->getRelation('tags');
    }
}
Run Code Online (Sandbox Code Playgroud)