总结:
一对一分辨方法(总体思路和多对多一致):
一、先要弄清楚哪个是父模型,哪个是子模型;
1、使用 hasOne 的时候,当前模型就是父模型, hasOne 里面的模型是子(外)模型;
2、使用 belongsTo 的时候,当前模型是子模型, belongsTo 里面的模型是父(本)模型;
二、然后,根据这个规则来区分 foreign_key 和 local_key/other_key 的取向。
foreign_key 永远是子模型的字段
other_key 和 local_key 永远是父(本)模型的字段
(一/多)对多的时候分辨(总体思路和一对一一致):
在某一个class里面,class_name所对应的表为主表(父/本),
关系函数方法里面的第一个参数所对应的表为从属表(子/外),
即为与主表相关联的表。
$has~
1、外键保存在关联表中;
2、保存时自动更新关联表的记录;
3、删除主表记录时自动删除关联记录。
$belongsTo
1、外键放置在主表中;
2、保存时不会自动更新关联表的记录;
3、删除时也不会更新关联表的记录。
---------------
以上两个步骤就可以清楚的区分如何取字段;下面是例子。
hasOne():
//User 父模型里面有 子模型 Phone
return $this->hasOne('App\Phone', 'foreign_key', 'local_key'); //User 是父模型, Phone 是子模型。这时候 foreign_key 外键就是 子模型 Phone 表里面的字段名, local_key 是 父模型 User 表里面的字段
结果:
return $this->hasOne('App\Phone', 'phone.user_id', 'user.id');
belongsTo():
//Phone 子模型,隶属于 User 父模型
return $this->belongsTo('App\User', 'foreign_key', 'other_key'); // User 模型还是父模型; foreign_key 是子模型 Phone 的字段; other_key 是父模型的字段
结果:
return $this->belongsTo('App\User', 'Phone.user_id', 'user.id');
一对一
一对一关联是一个非常简单的关联关系,例如,一个User模型有一个与之对应的Phone模型。要定义这种模型,我们需要将phone方法置于User模型中,phone方法会调用 Eloquent 模型基类上hasOne方法并返回其结果:
hasOne('App\Phone'); } }
传递给hasOne方法的第一个参数是关联模型的名称,关联关系被定义后,我们可以使用 Eloquent 的动态属性获取关联记录。动态属性允许我们访问关联函数就像它们是定义在模型上的属性一样:
$phone = User::find(1)->phone;
Eloquent 默认关联关系的外键基于模型名称,在本例中,Phone模型默认有一个user_id外键,如果你希望重写这种约定,可以传递第二个参数到hasOne方法:
return $this->hasOne('App\Phone', 'foreign_key');
此外,Eloquent 假设外键应该在父级上有一个与之匹配的id,换句话说,Eloquent 将会通过 user 表的 id 值去 phone 表中查询 user_id 与之匹配的 Phone 记录。如果你想要关联关系使用其他值而不是id,可以传递第三个参数到hasOne来指定自定义的主键:
return $this->hasOne('App\Phone', 'foreign_key', 'local_key'); //User 是父模型, Phone 是子模型。这时候 foreign_key 外键就是 子模型 Phone 表里面的字段名, local_key 是 父模型 User 表里面的字段
结果:
return $this->hasOne('App\Phone', 'phone.user_id', 'user.id');
定义相对的关联
我们可以从User中访问Phone模型,相应的,我们也可以在Phone模型中定义关联关系从而让我们可以拥有该 phone 的 User。我们可以使用 belongsTo 方法定义与 hasOne 关联关系相对的关联:
belongsTo('App\User'); } }
在上面的例子中,Eloquent 将会尝试通过 Phone 模型的 user_id 去User 模型查找与之匹配的记录。Eloquent 通过关联关系方法名并在方法名后加_id后缀来生成默认的外键名。然而,如果 Phone 模型上的外键不是user_id,也可以将自定义的键名作为第二个参数传递到belongsTo方法:
/** * 获取手机对应的用户 */ public function user(){ return $this->belongsTo('App\User', 'foreign_key'); }
如果父模型不使用id作为主键,或者你希望使用别的列来连接子模型,可以将父表自定义键作为第三个参数传递给belongsTo方法:
/** * 获取手机对应的用户 */ public function user(){ return $this->belongsTo('App\User', 'foreign_key', 'other_key'); // User 模型还是父模型; foreign_key 是子模型 Phone 的字段; other_key 是父模型的字段 }