سؤال

Summary

I am building a music discovery service. My question is: How do I insert data into the three-way pivot table Tag_Track_User ?

Schema

I have this schema seen here at LaravelSD

It comprises of six main tables (and a few others): Artists, Albums, Tracks, Tags, Users and Tag_Track_User

Schema

The Artists->Albums->Tracks relationship is straightforward and as you'd expect.

Tags, Tracks and Users all relate to one-another as no two can exist without the third.

Relationships

Artists hasMany() Albums

Albums hasMany() Tracks and belongsTo() an Artist

Tracks belongsTo() Albums

Tracks belongsToMany() Tags and belongsToMany() an Users

Tags belongsToMany() Tracks and belongsToMany() an Users

Users belongsToMany() Tags and belongsToMany() an Tracks

Models

User model

public function tags()
{
    return $this->belongsToMany('Tag', 'tag_track_user', 'user_mdbid', 'tag_mdbid')->withPivot('track_mdbid');
}

/**
 * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
 */
public function tracks()
{
    return $this->belongsToMany('Track', 'tag_track_user', 'user_mdbid', 'track_mdbid')->withPivot('tag_mdbid');
}

The Tag and Track model contain the same respective relationships.

Question

So my question is:

How do I insert data into the Tag_Track_User table? The tag_track_user table is a 3-way pivot table cointaining information about tracks that users have tagged.

You have to be logged in to tag a track (which means I have access to the user’s ID). The tracks ID is accessed as I am displaying it on the page where the form is contained. The tag on the other hand; if it already exists in the tags table, I want to get it’s ID and re-use that (as they are unique), if not, I want to create it, assign it an ID and insert that into the tag_track_user_table.

  1. I need to check whether the Tag exists
  2. If it does, get it's ID
  3. Insert data into the Tag_Track_User table

Thank you

Any help I receive on this, is greatly appreciated.

هل كانت مفيدة؟

المحلول

Well:

$tag = Tag::firstOrCreate(array('text' => $tag_text));

TagTrackUser::create(array(
    "tag_mdbid" => $tag->mdbid,
    "track_mdbid" => $track->mdbid,
    "user_mdbid" => Auth::user()->mdbid
));

Something like that? firstOrCreate does what the name says it does, the rest is pretty straightforward Eloquent.

نصائح أخرى

Since seems that there is not an appropriate pattern in Laravel, the cleaner and easier way is to implement any three-pivot-relationships via a model dedicated to the pivot table:

class Track
public function trackTags()
{
    return $this->hasMany('TagTrack');
}

...
class Tag
public function tagTracks()
{
    return $this->hasMany('TagTrack');
}

...
class TagTrack
public function track()
{
    return $this->belongsTo('Track');
}
public function tag()
{
    return $this->belongsTo('Tag');
}
public function anotherRelationship(){
...
}

You can do:

$track->trackTags->myCustomPivotDataAndRelationship()

and in TagTrack you have freedom to add as many relationship and field I want

Note than you can still keep the many to many to use when you don't need to access pivot relationships

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top