我们将逐个探讨不同的关联类型并解释一下应该什么时候使用它们。 一对一
一对一关联是目前存在的最基本的关联。这种关联意味着 A 模型只能链接到 B 模型,相反也是如此。举个例子,一个 User 模型和一个 Passport 模型会成为一对一的关联。一个用户只能拥有一张通行证,同样,一张通行证也只属于一个用户。
让我们看看如何在代码中定义这种关联。
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
public function passport() {
return $this->hasOne(App\Passport::class);
}
}
在 User 模型中我们创建了一个 passport 方法。我们通过 hasOne 方法告诉 Laravel User 模型有一个 Passport 。
注意:
所有用于定义关联的方法都有可选的额外参数,你可以在这些参数中定义本地键和外键。默认情况下,Laravel会假设你在用户模型中定义了 passport_id ,因为你试图创建与 passport 模型的关联。创建迁移文件时也请注意这一点!
在 Passport 模型中,我们需要定义逆向的关联。我们要让 Passport 模型知道它属于 User 模型。我们可以使用 belongsTo 方法来实现这一点。
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Passport extends Model
{
public function user() {
return $this->belongsTo(App\User::class);
}
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
public function invoices() {
return $this->hasMany(App\Invoice::class);
}
}
它看起来就像我们之前用于定义一对一关联的代码,对吧?
我们现在要做的就是让 Invoice 模型知道它属于 User 模型。 让我们定义一对多关联的反向对应关联吧。
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Invoice extends Model
{
public function user() {
return $this->belongsTo(App\User::class);
}
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Invoice extends Model
{
public function products() {
return $this->belongsToMany(App\Product::class);
}
}
你可以像这样定义这种关联的反向关系:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
public function invoices() {
return $this->belongsToMany(App\Invoice::class);
}
}
多对多关联实现起来稍微困难一些,因为它们需要数据库中的中间表。 你可以通过创建迁移文件在 Laravel 中创建此中间表。 远程关联 远程一对一
has one through 关联通过单个中间关联模型实现。 如果每个供应商都有一个用户,并且每个用户与一个用户历史记录相关联,那么供应商可以通过用户访问用户的历史记录。
这就是定义这种关联所需的数据库表:
suppliers:
- idproducts:
- id
- supplier_idproduct_history:
- id
- product_id
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Supplier extends Model
{
public function productHistory() {
return $this->hasOneThrough(App\History::class, App\Product::class);
}
}
传递给 hasOneThrough 方法的第一个参数是希望访问模型的名称。 第二个参数是中间模型的名称。 远程一对多
「has many through」 关联相当于 「has one through」 关联,只是对于多个记录的。 让我们使用前面的示例,但我们改变一件事:产品现在可以有多个历史条目而不是一个。 数据库表保持不变。
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Supplier extends Model
{
public function productHistory() {
return $this->hasManyThrough(App\History::class, App\Product::class);
}
}
这样,供应商模型可以访问产品的历史记录条目。 查询关联
查询一个关联非常简单。因为我们定义了 Passport 的一对一关联和 Invoice 的一对多关联,所以我们可以在 User 模型中使用它们。在 User 模型的每个实例上,我们都可以得到对应的 Passport 和 Invoice。