【问题标题】:Issue with Laravel Eloquent Many-to-Many relationshipLaravel Eloquent 多对多关系的问题
【发布时间】:2014-05-24 08:55:36
【问题描述】:

我有以下设置,三个表,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 长度的字母数字字段之前。我怎样才能让它工作?

【问题讨论】:

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


    【解决方案1】:

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

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

    tags() 函数将返回一个 HasMany 对象,该对象表示多对多关系 getResults() 函数返回关系的结果,这意味着在您的情况下与轨道相关的标签。 我希望这会有所帮助

    【讨论】:

    • @Mike 试试 $track->tags()->getResults();
    • 我看到的只是一个空的 JSON 对象。
    • 表示关系正常,请确保您的数据库中有数据
    • 那里有数据,但我没有得到相关的跟踪
    【解决方案2】:

    用于多对多的关系是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;
    });
    

    【讨论】:

    • 这似乎关系正在运作。确保您的数据库中有一些有效记录,用于 id 为 1 的 tag_mdbid 以及与这些记录相关联的相应曲目。
    • 当我取消注释 $tag = Tag::where('mdbid', '=', 'mR3YQxbayRP1RwGzvEJvXe1BcFPukMSP'); 行时,它会提取标签的详细信息,数据透视表基于两个 mdbids(32 个字母数字字符)
    • 当数据透视表中的tag_mdbidtrack_mdbid 是整数时有效,但当它们是字母数字ID 时无效。有什么原因吗?
    【解决方案3】:

    在 Track 模型上将 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 上设置关系?

    【讨论】:

    • 这不显示任何内容。我得到一个空的 JSON 对象。
    • 运行 DB::getQueryLog();最后检查查询,然后在您的数据库中运行它以确保您有数据要检索
    • 我把这个放在哪里?我已经设置了路由db 来返回 DB::getQueryLog();但它没有显示任何内容
    • 我现在返回了三个结果...(这是正确的)//$track = Track::whereMdbid('2CLc8V5frNy3U0UzjyXvATPWhUGu0Y2z'); $track = Track::find(1); return $track->tags; 但我无法指定曲目?
    猜你喜欢
    • 2019-06-13
    • 1970-01-01
    • 2019-03-26
    • 1970-01-01
    • 2013-05-15
    • 2014-09-27
    • 1970-01-01
    • 2013-02-09
    • 2014-11-11
    相关资源
    最近更新 更多