作者:feng2502863897 | 来源:互联网 | 2023-09-10 13:48
laravel的官方文档上面只介绍了belongsToMany的4个参数,文档如下:
到这里为止,官方文档上面对于多对多关联介绍差不多完了,如果想查看更多请看官方文档。
下面我来介绍在我们遇到两个表进行多对多关联,而且关联的时候,设置这两个表与中间表的关联字段。
例如:
a表结构为:
id 主键,
tag 标识,
…………
b表结构为:
id 主键,
…………
a_b表结构为:
id 主键,
b_id,
a_tag
当我们遇到这种情况的时候,查看官方文档上并没有找到相关的处理方法,官方文档上面的介绍整体说下来 :
belongsToMany(关联表模型,中间表表名,中间表与当前模型的关联字段,中间表与关联表的关联字段);
如果我们上面的表结构按照这种方式关联,假设我们当前模型为a ; 那么关联写为 belongsToMany(b:class, 'a_b', 'a_tag', 'b_id');
如果我们这么写的话,产生出来的sql为:
select * from b inner join a_b on b.id = a_b.id where a_b.a_tag = a.id;
这样问题就出现了,我们实际上想要的sql语句为:
select * from b inner join a_b on b.id = a_b.id where a_b.a_tag = a.tag;
但是,我们应该怎么做才可以得到这样的结果呢?
那就需要看下关于belongsToMany()的第四、第五个参数了;
我先贴上laravel源码:
public function belongsToMany($related, $table = null, $foreignPivotKey = null, $relatedPivotKey = null,$parentKey = null, $relatedKey = null, $relation = null){// If no relationship name was passed, we will pull backtraces to get the// name of the calling function. We will use that function name as the// title of this relation since that is a great convention to apply.if (is_null($relation)) {$relation = $this->guessBelongsToManyRelation();}// First, we'll need to determine the foreign key and "other key" for the// relationship. Once we have determined the keys we'll make the query// instances as well as the relationship instances we need for this.$instance = $this->newRelatedInstance($related);$foreignPivotKey = $foreignPivotKey ?: $this->getForeignKey();$relatedPivotKey = $relatedPivotKey ?: $instance->getForeignKey();// If no table name was provided, we can guess it by concatenating the two// models using underscores in alphabetical order. The two model names// are transformed to snake case from their default CamelCase also.if (is_null($table)) {$table = $this->joiningTable($related);}return $this->newBelongsToMany($instance->newQuery(), $this, $table, $foreignPivotKey,$relatedPivotKey, $parentKey ?: $this->getKeyName(),$relatedKey ?: $instance->getKeyName(), $relation);
上面是源码,我们主要看
return $this->newBelongsToMany($instance->newQuery(), $this, $table, $foreignPivotKey,$relatedPivotKey, $parentKey ?: $this->getKeyName(),$relatedKey ?: $instance->getKeyName(), $relation);
我们看了上面的代码后明确知道了,belongsToMany()有7个参数,我们通过官方文档已经知道了前四个参数的作用,剩下两个参数只能我们自己通过源码来研究
$instance->newQuery(),$this, $table, $foreignPivotKey
返回值中的这几个参数我就不多做描述了,我主要描述:
$relatedPivotKey, $parentKey ?: $this->getKeyName(),$relatedKey ?: $instance->getKeyName()
这两个,也就是belongsToMany的第5、6个参数
第五个参数,我看了他的主要功能为判断是否传入该参数如果没有传入这个参数就去调用getKeyName(); 有的人要问了getKeyName()是干什么的呢?我也想问,然后我就继续查看了geiKeyName()的源码。这个方法是Model类的一个方法,用来获取表主键的.这仅仅说了getKeyName()方法,不是还有个$this没有说它到底指向的谁?它指向的是当前调用belongsToMany()的模型。
第六个参数与第五个参数作用是一样的,只是获取的模型不同而已。这个参数获取的是关联表的主键.
参数讲完了,我们传入后会得到什么样的sql呢?
belongsToMany(b:class, 'a_b', 'a_tag', 'b_id', 'tag', 'id');
下面我们就来看看到底会得到怎样的sql:
select * from b inner join a_b on b.id = a_b.id where a_b.a_tag = a.tag ; 这就是我们得到的sql;
仔细看看,是不是和我们上面想要得到的sql语句一样?