Laravel三桌枢轴

时间:2014-04-17 15:16:34

标签: mysql laravel many-to-many pivot eloquent

音乐探索网站

摘要

我正在使用 Laravel 来创建音乐搜索/发现网站。简而言之,艺术家有许多专辑,其中包含许多曲目用户有许多标记曲目相关联。 TAGGING只能在跟踪,而非专辑或艺术家身上完成。

用户访问该网站并可以搜索一组标记,例如“快乐”,“派对”,“学校”。返回曲目列表以及其他一些细节。

用户首先标记了曲目。用户应该能够看到他们标记的所有曲目,并且能够根据标签进行搜索/过滤。

问题

使用我当前的设置(参见下面的表格结构),无法确定哪个用户标记了特定的曲目。我正在考虑将两个表 tag_track tag_user 合并为一个。新表的结构为:

Tag_Track_User表

Tag_ID
Track_ID
User_ID

我的问题

  1. 如果我这样做,我在模特上建立了什么样的关系
  2. 如何获取与标记关联的所有曲目( tags.text
  3. 当前表结构

    用户表

    User_ID (UNI)
    User_Name
    

    艺术家表

    Artist_ID (UNI)
    Artist_Name
    

    专辑表

    Album_ID (UNI)
    Album_Title
    Artist_ID
    

    跟踪表

    Track_ID (UNI)
    Track_title
    Album_ID
    

    标签表

    Tag_ID (UNI)
    Tag_text (UNI)
    

    Tag_Track表

    Tag_ID
    Track_ID
    

    Tag_User表

    Tag_ID
    User_ID
    

    模型结构

    艺术家模特

    有很多 Tlbums

    专辑模型

    属于相册 有很多曲目

    跟踪模型

    属于相册 有很多曲目

    用户模型

    属于许多标签

    标签模型

    属于许多曲目 属于许多用户

1 个答案:

答案 0 :(得分:1)

你对数据透视表是正确的。它必须包含3个键,因为在这种情况下,如果没有用户或轨道,标签就不能存在。所以这是3个模型之间的关系。

所以这就是你所需要的(我正在跳过艺术家和专辑的关系):

// pivot table tag_track_user: tag_id, track_id, user_id, id, timestamps

// Tag model
public function users()
{
    // by default only 2 keys are on the pivot, so lets add the third
    return $this->belongsToMany('User', 'tag_track_user')->withPivot('track_id'); 
}

public function tracks()
{
    return $this->belongsToMany('Track', 'tag_track_user')->withPivot('user_id'); 
}
------------
// Track model
public function tags()
{
    return $this->belongsToMany('Tag', 'tag_track_user')->withPivot('user_id'); 
}

public function users()
{
    return $this->belongsToMany('User', 'tag_track_user')->withPivot('tag_id'); 
}
------------
// User model
public function tags()
{
    return $this->belongsToMany('Tag', 'tag_track_user')->withPivot('track_id');
}

public function tracks()
{
    return $this->belongsToMany('Track', 'tag_track_user')->withPivot('tag_id'); 
}

现在,通过此设置,您可以获得所需的一切:

$user->tags->first()->users; // other users who used given tag
Tag::where('name','happy')->first()->tracks; // all tracks tagged 'happy'
$user->tracks()->where('title','Happy')->first()->tags; // all tags attached to song Happy
$user->tags->load('tracks')->fetch('tracks')->collapse(); // array of all the tracks related to all tags of a user (as arrays not models)
etc.

当然上面会导致一些数据库查询,但这是正常的。