多列枢轴雄辩的关系

Background: The application in question allows users to apply tags from a list of available tags. One article can have many tags and each tag may belong to many articles. The relationship between those is fine, but the complication comes in that a user should only see the tags which they have applied to the article. For instance, if Alice applies ['Apple', 'Banana', 'Cherry'] to article #1, Alice should not see Bob's article #1 tags of ['Grape', 'Orange', 'Kiwi'].

Ideal: An attach would work where the Auth'd user accesses the tags and applies it to an article by creating records in the intermediate pivot table. Additionally, if a user has applied a tag that does not exist yet, they should be able to insert new tags in the same action.

This action would be similar to how tags are applied to a StackOverflow post, actually.

The code I currently works, but just barely, so I wanted to see how others might organize the relationships between these. I'm also open to using a package if one exists that can handle this logic.

Relationships:

class User extends Authenticatable
{

    public function articles()
    {
        return $this->hasMany('\App\Article');
    }

    public function articles_tags()
    {
        return $this->belongsToMany('\App\Article_Tag', 'article_tag_user', 'article_tag_id','user_id');
    }
}


class Article extends Model
{

    public function tags()
    {
        return $this->belongsToMany('\App\Tag', 'article_tag');
    }

    public function user()
    {
        return $this->belongsTo('\App\User', 'user_id');
    }

    public function article_tag_user()
    {
        return $this->hasManyThrough('\App\Tag', '\App\Article_Tag_User', 'article_id', 'id', 'article_id', 'tag_id');
    }
}



class Tag extends Model
{

    protected $fillable = [
        'name'
    ];

    public function user()
    {
        return $this->belongsToMany('\App\User', 'article_tag_user', 'id', 'article_tag_id');
    }

    public function articles()
    {
        return $this->belongsToMany('\App\Article', 'article_tag');
    }
}



class Article_Tag extends Model
{
    protected $table = 'article_tag';

    public function user()
    {
        return $this->belongsToMany('\App\User', 'article_tag_user', 'user_id', 'article_tag_id');
    }

    public function tags()
    {
        return $this->belongsTo('\App\Tag');
    }
}


class Article_Tag_User extends Model
{
    protected $table = 'article_tag_user';

    public function tags()
    {
        return $this->hasManyThrough('\App\Tag', '\App\Article_Tag');
    }

}

Table Schema


Tag Table

|id|name|

Article_Tag Table

|id|article_id|tag_id|

Article_Tag_User

|id|user_id|article_tag_id|

You only need one pivot table (it also doesn't need an id):

article_tag_user: article_id | tag_id | user_id

Then you have BelongsToMany relationships between all combinations of Article, Tag, User.