laravel学习教程之关联模型(3)

正如你已经了解到的。定义多对多的关联需要引入一个中间表。Eloquent 提供了几种非常有帮助的方式来与这个表进行交互。比如,让我们假定我们的 User 对象关联到了很多 Role 对象。在访问这些关联对象时,我们可以通过在模型上使用 pivot 属性来访问中间表:

$user = App\User::find(1); foreach ($user->roles as $role) { echo $role->pivot->created_at; }

注意我们取出的每个 Role 对象,都会被自动的分配 pivot 属性。这个属性包含了一个代表中间表的模型,并且可以像其他 Eloquent 模型一样被使用。

默认的,只有模型的键会被 pivot 对象提供,如果你的中间表包含了额外的属性,你必须在定义关联时指定它们:

return $this->belongsToMany('App\Role')->withPivot('column1', 'column2');

如果你想要中间表自动维护 created_at 和 updated_at 时间戳,你可以在定义关联时使用 withTimestamps 方法:

return $this->belongsToMany('App\Role')->withTimestamps();

通过中间表字段过滤关系

你可以通过在定义关联时使用 wherePrivot 和 wherePivotIn 方法来在返回的结果中进行过滤:

return $this->belongsToMany('App\Role')->wherePivot('approved', 1); return $this->belongsToMany('App\Role')->wherePivotIn('approved', [1, 2]);

远程一对多

远程一对多关联提供了简短便捷的方法通过中间关联件来访问远端的关联。比如,一个 Country 模型应该通过 User 模型可以拥有很多的 Post 模型。在这个例子中,你可以非常容易的就检索出一个国家中的所有的文章。让我们来看一下定义这些关联所需要的表:

countries id - integer name - string users id - integer country_id - integer name - string posts id - integer user_id - integer title - string

远端的 posts 并没有包含 country_id 列,hasManyThrough 关联可以通过 $country->posts 来访问一个国家的文章。为了执行这个查询,Eloquent 会通过中间表 users 的 country_id 来检索 posts 表中用户 ID 相匹配的记录。

现在我们已经明确了关联表的结构,那么让我们来在 Country 模型上定义关联:

<?php namespace App; use Illuminate\Database\Eloquent\Model; class Country extends Model { /** * Get all of the posts for the country. */ public function posts() { return $this->hasManyThrough('App\Post', 'App\User'); } }

传递到 hasManyThrough 方法的第一个参数是我们最终想要访问到的模型,而第二个参数则是中间层的模型名称。

当使用关联查询时,通常 Eloquent 会遵循外键约定。如果你希望对关联的键进行自定义,你可以传递第三和第四个参数到 hasManyThrough 方法。第三个参数是中间层模型的外键名称,第四个参数是最终想要获取的模型中的所对应的中间层的外键, 而第五个参数则是当前模型的主键:

class Country extends Model { public function posts() { return $this->hasManyThrough( 'App\Post', 'App\User', 'country_id', 'user_id', 'id' ); } }

多态关联

表结构

多态关联允许一个模型在单个关联中从属一个或多个其它模型。比如,想象一下应用中的用户可以喜欢文章及其评论。如果使用多态关联,那么你就可以使用一个单独的 likes 表来关联这两个场景。首先,让我们确定定义这种关联所需要的表结构:

posts id - integer title - string body - text comments id - integer post_id - integer body - text likes id - integer likeable_id - integer likeable_type - string

你需要注意到的两个在 likes 表中重要的字段 likeable_id 和 likeable_type。likeable_id 字段会包含文章或者评论的 ID 值,而 likeable_type 字段会包含其所属的模型的类名。likeable_type 就是当访问 likeable 关联时 ORM 用来判断所属的模型是哪个类型。

模型结构

接着,让我们检查一下这个关联所需要的模型定义:

<?php namespace App; use Illuminate\Database\Eloquent\Model; class like extends Model { /** * Get all of the owning likeable models. */ public function likeable() { return $this->morphTo(); } } class Post extends Model { /** * Get all of the post's likes. */ public function likes() { return $this->morphMany('App\Like', 'likeable'); } } class Comment extends Model { /** * Get all of the comment's likes. */ public function likes() { return $this->morphMany('App\Like', 'likeable'); } }

获取多态关联

一旦数据库表和模型都定义完成,你就可以在你的模型中访问这些关联。比如,你可以使用 likes 动态属性来访问文章中所有关联的 likes 模型:

$post = App\Post::find(1); foreach ($post->likes as $like) { // }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/5ca46c020df88a8c2b8e1156d1574bf3.html