Laravel 模型关联基础教程详解
在Laravel中定义模型关联是每个Laravel开发者可能已经做过不止一次的事情。但是在试图实现关联时可能会遇到各种问题。因为Laravel有各种各样的关联,你应该选择哪一个?当涉及到查询模型时,我们如何充分利用模型关联的功能?
Laravel的模型关联可能会让人糊涂。如果你不完全理解Laravel的关联在这一点上是如何工作的,别担心,读完这篇文章后,你会更好地理解它。
我们应该使用哪个模型关联?
要回答这个问题,首先你要知道有哪些可用的选项。Laravel有3种不同的关联类型。
- 一对一
- 一对多
- 多对多
我们将逐个探讨不同的关联类型并解释一下应该什么时候使用它们。
一对一
一对一关联是目前存在的最基本的关联。这种关联意味着A模型只能链接到B模型,相反也是如此。举个例子,一个User模型和一个Passport模型会成为一对一的关联。一个用户只能拥有一张通行证,同样,一张通行证也只属于一个用户。
让我们看看如何在代码中定义这种关联。
hasOne(App\Passport::class); } }
在User模型中我们创建了一个passport方法。我们通过hasOne方法告诉LaravelUser模型有一个Passport。
注意:
所有用于定义关联的方法都有可选的额外参数,你可以在这些参数中定义本地键和外键。默认情况下,Laravel会假设你在用户模型中定义了passport_id,因为你试图创建与passport模型的关联。创建迁移文件时也请注意这一点!
在Passport模型中,我们需要定义逆向的关联。我们要让Passport模型知道它属于User模型。我们可以使用belongsTo方法来实现这一点。
belongsTo(App\User::class); } }
一对多
你可以在Laravel中定义的下一个关联是一对多关联。这种类型的关联意味着一个类型A的模型可以链接到多个类型B的模型。但是类型B的模型只属于一个类型A的模型。
例如,User模型和Invoice模型之间的关联是一对多关联。用户可以拥有多个账单,但账单仅属于一个用户。
在代码中是这样写的:
hasMany(App\Invoice::class); } }
它看起来就像我们之前用于定义一对一关联的代码,对吧?
我们现在要做的就是让Invoice模型知道它属于User模型。让我们定义一对多关联的反向对应关联吧。
belongsTo(App\User::class); } }
多对多
最后要定义的关联是多对多关联。这种类型的关联意味着类型A的一个模型可以链接到类型B的多个模型,反之亦然。
例如,Invoice 模型和Product 模型之间的关联将是多对多关联。账单可以包含多个产品,而产品可以属于多个账单。
belongsToMany(App\Product::class); } }
你可以像这样定义这种关联的反向关系:
belongsToMany(App\Invoice::class); } }
多对多关联实现起来稍微困难一些,因为它们需要数据库中的中间表。你可以通过创建迁移文件在Laravel中创建此中间表。
远程关联
远程一对一
hasonethrough关联通过单个中间关联模型实现。如果每个供应商都有一个用户,并且每个用户与一个用户历史记录相关联,那么供应商可以通过用户访问用户的历史记录。
这就是定义这种关联所需的数据库表:
suppliers: -idproducts: -id -supplier_idproduct_history: -id -product_id
即使product_history表不包含supplier_id列,供应商也可以通过使用「hasonethrough」关系访问product_history记录。
hasOneThrough(App\History::class,App\Product::class); } }
传递给hasOneThrough方法的第一个参数是希望访问模型的名称。第二个参数是中间模型的名称。
远程一对多
「hasmanythrough」关联相当于「hasonethrough」关联,只是对于多个记录的。让我们使用前面的示例,但我们改变一件事:产品现在可以有多个历史条目而不是一个。数据库表保持不变。
hasManyThrough(App\History::class,App\Product::class); } }
这样,供应商模型可以访问产品的历史记录条目。
查询关联
查询一个关联非常简单。因为我们定义了Passport的一对一关联和Invoice的一对多关联,所以我们可以在User模型中使用它们。在User模型的每个实例上,我们都可以得到对应的Passport和Invoice。
passport->expiration_date; //查询invoice关联 foreach($user->invoicesas$invoice){ $invoice->total_amount; }
也可以查询关联的反向关联。如果您有账单,则可以获得该账单的用户。
user->first_name;
查询多对多关联的工作方式与其他关联完全相同。此外,多对多关联有一个pivot属性。此属性表示中间表,可以像任何其他模型一样使用。
举个例子,假设连接的表有created_at字段,我们就可以使用pivot来获取created_at字段。
productsas$product){ $product->pivot->created_at; }
查询hasonethrough和hasmanythrough的工作方式与其他关联完全相同。
添加约束
可以在查询时向关系添加约束。看看下面的示例:
passport()->where('active',1)->orderBy('expiration_date');
检查关联是否存在
有时候你希望检查模型中是否有添加某些关联,Laravel有一些方法可以帮助你用来检查:
get(); //找到没拥有护照的所有用户 $users=App\User::doesntHave('passport')->get(); //找到拥有5个及以上产品的发票 $invoices=App\Invoice::has('products','>=',5)->get();
希望这篇文章能让你对Laravel的模型关联有更好的理解。谢谢你的阅读!也希望大家多多支持毛票票。