与Laravel Eloquent多对多关系的问题

时间:2014-04-10 14:54:37

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

我有以下设置,三个表格,trackstagstag_track

tracks

CREATE TABLE `tracks` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `mdbid` varchar(32) COLLATE utf8_unicode_ci NOT NULL,
  `track_no` int(11) NOT NULL,
  `title` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `sort_title` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `safe_title` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `album_mdbid` varchar(32) COLLATE utf8_unicode_ci NOT NULL,
  `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  `deleted_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `tracks_mdbid_unique` (`mdbid`)
) ENGINE=InnoDB AUTO_INCREMENT=603 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

tags

CREATE TABLE `tags` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `mdbid` varchar(32) COLLATE utf8_unicode_ci NOT NULL,
  `text` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  PRIMARY KEY (`id`),
  UNIQUE KEY `tags_mdbid_unique` (`mdbid`),
  UNIQUE KEY `tags_text_unique` (`text`)
) ENGINE=InnoDB AUTO_INCREMENT=3376 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

tag_track

CREATE TABLE `tag_track` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `tag_mdbid` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `track_mdbid` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  PRIMARY KEY (`id`),
  KEY `tag_track_tag_mdbid_index` (`tag_mdbid`),
  KEY `tag_track_track_mdbid_index` (`track_mdbid`),
  CONSTRAINT `tag_track_track_mdbid_foreign` FOREIGN KEY (`track_mdbid`) REFERENCES `tracks` (`mdbid`) ON DELETE CASCADE,
  CONSTRAINT `tag_track_tag_mdbid_foreign` FOREIGN KEY (`tag_mdbid`) REFERENCES `tags` (`mdbid`) ON DELETE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

Track

class Track extends \Eloquent {

  // Add your validation rules here
  public static $rules = [
    // 'title' => 'required'
  ];

  // Don't forget to fill this array
  protected $fillable = [];

    public function album() {
        return $this->belongsTo('Album', 'album_mdbid', 'mdbid');
    }

    public function getTags() {
        return $this->hasMany('Tag', 'tag_track', 'tag_mdbid', 'track_mdbid');
    }

}

Tag

class Tag extends \Eloquent {

  // Add your validation rules here
  public static $rules = [
    // 'title' => 'required'
  ];

  // Don't forget to fill this array
  protected $fillable = [];

    public function getTracks() {
        return $this->hasMany('Track', 'tag_track', 'tag_mdbid', 'track_mdbid');
    }
}

Routes

Route::get('/', function()
{
    // When I uncomment the line below it finds the tag details
    // $tag = Tag::where('mdbid', '=', 'mR3YQxbayRP1RwGzvEJvXe1BcFPukMSP');
    $track = Track::find(1);
    return $track->tags;
});

当我在浏览器中进入路线时,没有显示任何内容

更新

我现在已经显示了正确的结果数,但只有在将数据透视表更改为整数之后才能使用32长度的字母数字字段。我怎样才能让它发挥作用?

3 个答案:

答案 0 :(得分:0)

将轨道模型上的getTags()更改为tags(),或使用您在模型上定义的$ track-> getTags。

由于标签和曲目之间存在多对多的关系,因此请更改定义:

// on Tag model
public function getTracks() {
    return $this->belongsToMany('Track', 'tag_track', 'tag_mdbid', 'track_mdbid');
}


// on Track model
public function getTags() {
    return $this->belongsToMany('Tag', 'tag_track', 'track_mdbid', 'tag_mdbid');
}

为什么你不想在主要ID上设置关系但是mdbids?

答案 1 :(得分:0)

尝试将函数getTags()重命名为tags(),然后使用

$track->tags()->getResults();

tags()函数将返回一个HasMany对象,此对象表示多对多关系,getResults()函数返回关系结果,表示与您案例中的轨道相关的标记。 我希望这会有所帮助

答案 2 :(得分:0)

用于多对多的关系是belongsToMany(),而且你也有一些外键无序。

getTracks()更改为return $this->belongsToMany('Track', 'tag_track', 'track_mdbid', 'tag_mdbid');

getTags()更改为return $this->belongsToMany('Tag', 'tag_track', 'tag_mdbid', 'track_mdbid');

此外,正如其他人所指出的那样,您必须将这些功能名称更改为tags()tracks(),或在尝试使用它们时适当调用它们。

Route::get('/', function()
{
    // When I uncomment the line below it finds the tag details
    // $tag = Tag::where('mdbid', '=', 'mR3YQxbayRP1RwGzvEJvXe1BcFPukMSP');
    $track = Track::find(1);
    return $track->getTags;
});