【问题标题】:Laravel pivot tables with non primary keys带有非主键的 Laravel 数据透视表
【发布时间】:2018-08-31 17:39:00
【问题描述】:

在 Laravel 中,我有一个具有自定义主键的模型。我创建了一个必须使用唯一递增键的数据透视表,因此我无法获取任何数据透视表。

媒体模型

class Media
{
    protected $primaryKey = 'ref_id';
    public $incrementing = false;

    ...
}

页面模型

class Page
{
    public function media()
    {
        return $this->belongsToMany('App\Models\Media');
    }

    ...
}

数据透视表

+----------+---------+
| media_id | page_id |
+----------+---------+
|     1    |    15   |
+----------+---------+
|     5    |    27   |
+----------+---------+

页面控制器

$pages = Page::with('media')->get();  

这将导致以下 sql 语句:

select 
    media.*, media_page.page_id as pivot_page_id, 
    media_page.media_id as pivot_media_id 
from media inner join media_page on media.ref_id = media_page.media_id
where media_page.page_id in ('15', '27')

正如您在 sql 语句的第 4 行所见,它引用的是 media.ref_id 而不是 media.id,因此显然没有返回任何结果。我明白为什么会这样。我需要知道的是如何更新 PageController 中的媒体方法,以便它使用id 而不是ref_id 进行这一查询。我无法更改媒体模型中的主键,因为它在其他地方大量使用。我尝试了以下方法,但似乎没有效果。

页面模型

class Page
{
    public function media()
    {
        $media = new Media();
        $media->setPrimaryKey('id');

        return $this->belongsToMany($media);
    }

    ...
}

谢谢

【问题讨论】:

    标签: laravel pivot-table primary-key


    【解决方案1】:

    如果您查看https://laravel.com/docs/5.6/eloquent-relationships 的文档,您会看到belongsToMany() 还接受其他参数来设置如何加入表格return $this->belongsToMany('App\Role', 'role_user', 'user_id', 'role_id');

    【讨论】:

    • 我已经试过了。 return $this->belongsToMany('\App\Models\Media', 'media_page', 'media_id', 'id');。这没有用。它产生了以下错误。 SQLSTATE [42S22]:找不到列:1054“字段列表”中的未知列“media_page.id”(SQL:选择媒体。*,media_page.media_id 作为 pivot_media_id,media_page.id 作为来自 media.ref_id 上的媒体内部连接 ​​page_media 的 pivot_id = page_media.id where page_media.media_id in (15,27))
    • 不应该返回$this->belongsToMany('\App\Models\Media', 'media_page', 'ref_id', 'media_it');吗?
    • 然后产生错误SQLSTATE[42S22]: Column not found: 1054 Unknown column 'media_page.ref_id' in 'field list' (SQL: select media.*, media_page.ref_id as pivot_ref_id, media_page.media_id as pivot_media_id from media inner join media_page on media.ref_id = media_page.media_id where media_page.ref_id in (15,27))。我根本不想使用 ref_id。我想从原来的 join 语句中删除 ref_id 并将其替换为 id
    • 抱歉,有点快。第一个键是链接到您的模型表的键,第二个是链接到另一个表的键。因此,不要设置您要加入的内容。不确定这是否可以使用 eloquent,也许您必须使用查询构建器,您可以更好地控制连接。你可以看看这是否会对你有更多的帮助stackoverflow.com/questions/24391759/…,尤其是 laravel 5.5 上的答案,你还有一个可选参数
    • 您的链接中接受的解决方案是我已经尝试过的。我暂时更改了主键以使用数据透视表,然后再次将其更改回来。它似乎与最终的 sql 语句没有任何不同。我将如何用这个实现查询生成器?控制器正在调用“with()”方法,该方法期望返回一个“belongsToMany”类型的对象。我可能应该提一下,我正在运行 Laravel 5.3 版。
    【解决方案2】:

    您可以从Laravel Documentation 传递表名以及要使用的外键。

    除了自定义连接表的名称外,您还可以通过将附加参数传递给 belongsToMany 方法来自定义表上键的列名。第三个参数是要定义关系的模型的外键名称,而第四个参数是要加入的模型的外键名称:

    return $this->belongsToMany('App\Role', 'role_user', 'user_id', 'role_id');

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-20
      • 2012-07-13
      相关资源
      最近更新 更多