Laravel 的属于多对关系在两个表上定义本地键

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24391759/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 09:41:58  来源:igfitidea点击:

Laravel belongsToMany relationship defining local key on both tables

phpsqldatabaselaravellaravel-4

提问by user1952811

So the belongsToMany relationship is a many-to-many relationship so a pivot table is required

所以belongsToMany 关系是多对多关系,所以需要一个数据透视表

Example we have a userstable and a rolestable and a user_rolespivot table.

例如,我们有一个users表、一个roles表和一个user_roles数据透视表。

The pivot table has two columns, user_id, foo_id... foo_idreferring to the idin roles table.

数据透视表有两列,user_id, foo_id...foo_id指的是idin 角色表。

So to do this we write the following in the usereloquent model:

为此,我们在usereloquent 模型中编写以下内容:

return $this->belongsToMany('Role', 'user_roles', 'user_id', 'foo_id');

return $this->belongsToMany('Role', 'user_roles', 'user_id', 'foo_id');

Now this looks for an idfield in userstable and joins it with the user_idfield in the user_rolestable.

现在,这个寻找一个id在外地users表,并与加入它user_id在该领域user_roles表。

Issue is I want to specify a different field, other than idto join on in the userstable. For example I have bar_idin the users table that I want to use as the local keyto join with user_id

问题是我想指定一个不同的字段,而不是id加入users表中。例如,我bar_id在 users 表中有我想用作local key加入的user_id

From laravel's documentation, it is not clear on how to do this. In other relationships like hasManyand belongsTowe can specify local keyand foriegn keybut not in here for some reason.

从 laravel 的文档中,不清楚如何做到这一点。在其他关系中,例如hasManyandbelongsTo我们可以指定local keyandforiegn key但由于某种原因不能在这里指定。

I want the local keyon the users table to be bar_idinstead of just id.

我希望local key用户表上的bar_id不是id.

How can I do this?

我怎样才能做到这一点?

回答by Jarek Tkaczyk

Update: as of Laravel 5.5onwards it is possible with generic relation method, as mentioned by @cyberfly below:

更新:从Laravel 5.5开始,可以使用通用关系方法,如下面的@cyberfly 所述:

public function categories()
{
    return $this->belongsToMany(
         Category::class,
         'service_categories',
         'service_id',
         'category_id', 
         'uuid',  // new in 5.5
         'uuid'   // new in 5.5
    );
}


for reference, previous method:

供参考,以前的方法:

I assume idis the primary key on your Usermodel, so there is no way to do this with Eloquent methods, because belongsToManyuses $model->getKey()to get that key.

我假设id是您User模型上的主键,因此无法使用 Eloquent 方法执行此操作,因为belongsToMany用于$model->getKey()获取该键。

So you need to create custom relation extending belongsToManythat will do what you need.

因此,您需要创建自定义关系扩展来belongsToMany满足您的需求。

A quick guess you could try: (not tested, but won't work with eager loading for sure)

您可以尝试快速猜测:(未测试,但肯定不会与急切加载一起使用)

// User model
protected function setPrimaryKey($key)
{
  $this->primaryKey = $key;
}

public function roles()
{
  $this->setPrimaryKey('desiredUserColumn');

  $relation = $this->belongsToMany('Role', 'user_roles', 'user_id', 'foo_id');

  $this->setPrimaryKey('id');

  return $relation;
}

回答by cyberfly

On Laravel 5.5 and above,

在 Laravel 5.5 及更高版本上,

    public function categories()
    {
        return $this->belongsToMany(Category::class,'service_categories','service_id','category_id', 'uuid', 'uuid');
    }

From the source code:

从源代码:

    public function belongsToMany($related, $table = null, $foreignPivotKey = null, $relatedPivotKey = null,
                                  $parentKey = null, $relatedKey = null, $relation = null)
    {}

回答by Kryten

This is a recently added feature. I had to upgrade to 4.1 because I was also looking for this.

这是最近添加的功能。我不得不升级到 4.1,因为我也在寻找这个。

From the API documentation:

API 文档

public BelongsToMany belongsToMany(string $related, string $table = null, string $foreignKey = null, string $otherKey = null, string $relation = null)

The $otherKeyand $relationparameters were added in 4.1. Using the $foreignKeyand $otherKeyparameters allows you to specify the keys on both sides of the relation.

$otherKey$relation参数4.1中添加。使用$foreignKey$otherKey参数允许您指定关系两侧的键。

回答by Gabriel

The best way is set the primary key.

最好的方法是设置主键。

class Table extends Eloquent {

     protected $table = 'table_name';

     protected $primaryKey = 'local_key';

回答by s6carlo

belongsToManyallows to define the name of the fields that are going to store che keys in the pivot table butthe method insert always the primary keyvalues into these fields.

ownToMany允许定义将要在数据透视表中存储键的字段的名称,该方法始终将主键值插入这些字段中。

You have to:

你必须:

  • define in the method belongsToManythe table and the columns;

  • then using protected $primaryKey= 'local_key'; you can choose which value store.

  • 在方法belongsToMany 中定义表和列;

  • 然后使用受保护的$primaryKey= 'local_key'; 您可以选择哪个值存储。

回答by blindMoe

I recently went through the same problem where I needed to have an associated table that used ID's to link two tables together that were not Primary Keys. Basically what I did was create a copy of my model that models the pivot table and set the Primary Key to the value that I wanted it to use. I tried creating a model instance, settings the primary key and then passing that to the relation but Laravel was not respecting the primary key I had set ( using the ->setPrimaryKey() method above ).

我最近遇到了同样的问题,我需要一个关联的表,该表使用 ID 将两个不是主键的表链接在一起。基本上我所做的是创建我的模型的副本,该副本对数据透视表进行建模并将主键设置为我希望它使用的值。我尝试创建一个模型实例,设置主键,然后将其传递给关系,但 Laravel 不尊重我设置的主键(使用上面的 ->setPrimaryKey() 方法)。

Making a copy of the model and setting the primary key feels a little bit 'hackish' but in the end it works as it should and since Pivot table models are generally very small I don't see it causing any problems in the future.

制作模型的副本并设置主键感觉有点“hackish”,但最终它可以正常工作,并且由于数据透视表模型通常非常小,我认为它不会在未来造成任何问题。

Would love to see a third key option available in the next release of Laravel that lets you get more specific with your linking.

希望在 Laravel 的下一个版本中看到第三个关键选项可用,让您可以更具体地进行链接。