Laravel 5.8 多对多关系使用自定义列名称作为数据透视表 table
Laravel 5.8 many to many relation using custom column names for pivot table
我有两个 tables user_details
和 location
如下:
user_details
user_id (INTEGER PRIMARY KEY)
......
location
id (INTEGER UNSIGNED PRIMARY KEY)
......
这两个 table 彼此之间存在多对多的关系。现在我正在使用一个枢轴 table location_user_details
如下所示
location_user_details
id (INTEGER UNSIGNED PRIMARY KEY),
user_id (INTEGER FOREIGN KEY REFERENCES use_details.user_id)
location_id (INTEGER FOREIGN KEY REFERENCES location.id)
type (VARCHAR)
型号UserDetails
的关系码如下:
class UserDetails extends Model
{
protected $primaryKey = 'user_id';
........
public function location(){
return $this->belongsToMany(Location::class, 'location_user_details', 'user_id', 'id')->withPivot('type');
}
}
型号Location
的关系码如下:
class Location extends Model
{
......
public function userDetails(){
return $this->belongsToMany(UserDetails::class, 'location_user_details', 'id', 'user_id')->withPivot('type');
}
}
现在在我的控制器中,我在通过以下代码保存 UserDetails
和 Location
对象后创建关系:
$userDetails->location()->attach($location->id, ['type'=>'HEADQUARTER']);
当代码执行到这一行时,出现以下异常:
SQLSTATE[HY000]: General error: 1364 Field 'location_id' doesn't have a default value (SQL: insert into location_user_details
(id
, type
, user_id
) values (1, HEADQUARTER, 0))
我想指出两件正在发生的事情。
- 位置字段未进入插入数据的查询。
user_id
值是 0
,当数据被插入 user_details
table.[=56 时,它应该大于 0
=]
这里提一下,当我去数据库中查找location
和user_details
table的数据时,发现所有的数据都被插入了。
现在我的问题是这段代码可能出了什么问题?
问题可能出在变量 $location 中,但在您创建它时并未显示。确保它是一个 Location 对象
好吧,我终于找到问题所在了。关于这个主题的文档不多。其实就在于函数belongsToMany
的使用。 belongsToMany
函数需要 up-to 7 个参数。到目前为止,我可以解码前 4 个参数。
第一个参数取相关模型的class。
第二个参数采用数据库中枢轴的名称table。
第三个参数采用数据透视表 table 中列的名称,该列引用了调用 belongsToMany
的模型。
第四个参数采用引用相关模型的数据透视表中列的名称 table。
因此,模型 UserDetails
中函数 location
的代码如下所示:
public function location(){
return $this->belongsToMany(Location::class, 'location_user_details', 'user_id', 'location_id')->withPivot('type');
}
模型 Location
中函数 userDetails
的代码如下所示:
public function userDetails(){
return $this->belongsToMany(UserDetails::class, 'location_user_details', 'location_id', 'user_id')->withPivot('type');
}
希望对其他人有所帮助。
我有两个 tables user_details
和 location
如下:
user_details
user_id (INTEGER PRIMARY KEY)
......
location
id (INTEGER UNSIGNED PRIMARY KEY)
......
这两个 table 彼此之间存在多对多的关系。现在我正在使用一个枢轴 table location_user_details
如下所示
location_user_details
id (INTEGER UNSIGNED PRIMARY KEY),
user_id (INTEGER FOREIGN KEY REFERENCES use_details.user_id)
location_id (INTEGER FOREIGN KEY REFERENCES location.id)
type (VARCHAR)
型号UserDetails
的关系码如下:
class UserDetails extends Model
{
protected $primaryKey = 'user_id';
........
public function location(){
return $this->belongsToMany(Location::class, 'location_user_details', 'user_id', 'id')->withPivot('type');
}
}
型号Location
的关系码如下:
class Location extends Model
{
......
public function userDetails(){
return $this->belongsToMany(UserDetails::class, 'location_user_details', 'id', 'user_id')->withPivot('type');
}
}
现在在我的控制器中,我在通过以下代码保存 UserDetails
和 Location
对象后创建关系:
$userDetails->location()->attach($location->id, ['type'=>'HEADQUARTER']);
当代码执行到这一行时,出现以下异常:
SQLSTATE[HY000]: General error: 1364 Field 'location_id' doesn't have a default value (SQL: insert into
location_user_details
(id
,type
,user_id
) values (1, HEADQUARTER, 0))
我想指出两件正在发生的事情。
- 位置字段未进入插入数据的查询。
user_id
值是0
,当数据被插入user_details
table.[=56 时,它应该大于0
=]
这里提一下,当我去数据库中查找location
和user_details
table的数据时,发现所有的数据都被插入了。
现在我的问题是这段代码可能出了什么问题?
问题可能出在变量 $location 中,但在您创建它时并未显示。确保它是一个 Location 对象
好吧,我终于找到问题所在了。关于这个主题的文档不多。其实就在于函数belongsToMany
的使用。 belongsToMany
函数需要 up-to 7 个参数。到目前为止,我可以解码前 4 个参数。
第一个参数取相关模型的class。
第二个参数采用数据库中枢轴的名称table。
第三个参数采用数据透视表 table 中列的名称,该列引用了调用 belongsToMany
的模型。
第四个参数采用引用相关模型的数据透视表中列的名称 table。
因此,模型 UserDetails
中函数 location
的代码如下所示:
public function location(){
return $this->belongsToMany(Location::class, 'location_user_details', 'user_id', 'location_id')->withPivot('type');
}
模型 Location
中函数 userDetails
的代码如下所示:
public function userDetails(){
return $this->belongsToMany(UserDetails::class, 'location_user_details', 'location_id', 'user_id')->withPivot('type');
}
希望对其他人有所帮助。