【问题标题】:Laravel three table pivotLaravel 三表枢轴
【发布时间】:2014-04-17 15:16:34
【问题描述】:

音乐探索网站

总结

我正在使用 Laravel 创建一个音乐搜索/发现网站。简而言之,艺术家有很多专辑,其中有很多曲目User 有许多与Tracks 关联的Tags标记只能在曲目上进行,不能在专辑或艺术家上进行。

用户访问该网站并可以搜索一组标签,例如“快乐”、“聚会”、“学校”。将返回曲目列表以及其他一些详细信息。

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

问题

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

Tag_Track_User 表

Tag_ID
Track_ID
User_ID

我的问题

  1. 如果我这样做,我要在模型上设置什么关系
  2. 如何获取与标签关联的所有曲目 (tags.text)

当前表结构

用户表

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

专辑型号

属于专辑 有许多曲目

履带型号

属于专辑 有许多曲目

用户模型

属于许多标签

标签模型

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

【问题讨论】:

  • 您为什么想知道谁标记了曲目?这些标签是个人的还是公共的?描述这些标签是什么以及用户如何将它们分配给曲目
  • 我已经更新了问题(在顶部添加了两段来解释“情况”)
  • 好的,所以标签是公开的,但你仍然没有说为什么你想知道是谁给这首歌加了标签。无论如何,您可以简单地在数据透视表 tag_track 上添加第三个 fk 字段来跟踪用户
  • 因为它是一个音乐发现网站,你可以找到与你相似的歌曲标签的其他人,因此你可能会喜欢他们的音乐。您能否举例说明如何在关系方​​面引用模型。

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


【解决方案1】:

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

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

// 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.

当然上面会引起一些db查询,但这是正常的。

【讨论】:

  • 我已经尝试过你的建议,但我“未定义的属性:Illuminate\Database\Eloquent\Builder::$tags”。这就是我正在使用的导致该错误的原因:“$user = User::whereUsername('mstnorris'); $user->tags->first()->users;”
  • 那么您在 User 模型上没有正确定义标签,或者数据透视表不完全符合预期,或者键错误...我粘贴的代码肯定有效,所以仔细检查您的模型和表格
  • 你在底部提供的代码,是完整的吗?我已经设置了一个路线“测试”,在那个闭包中,我想使用我的用户名自己尝试一下,所以我提取了所有与我相关的标签和曲目。我该怎么做?
  • $user = User::whereUsername('你')->first();然后剩下的......在'artisan tinker'中玩它比在浏览器中更容易。如果你不知道这个工具,你可以查看laracasts.com/lessons/tinkering-with-boris(可能是付费视频,但 Jeff 的 laracasts 是值得的)
  • 首先,感谢您的帮助,非常感谢。我有 ->get() 而不是 ->first()。有什么不同?我已经订阅了 laracasts,它们很棒,不是吗!另外,如何返回标签和跟踪详细信息(不仅仅是 ID)?
猜你喜欢
  • 2020-07-29
  • 1970-01-01
  • 1970-01-01
  • 2022-01-22
  • 2020-05-06
  • 1970-01-01
  • 2019-07-05
  • 1970-01-01
相关资源
最近更新 更多