One To One
UsermodelがPhoneモデルに関連付けられていると仮定します。このような関連付けを定義するには、hasOneメソッドで定義された関連付けを返すPhoneメソッドをUserモデルに定義する必要があります。
<?phpnamespace App;use Illuminate\Database\Eloquent\Model;class User extends Model{ /** * Get the phone record associated with the user. */ public function phone() { return $this->hasOne('App\Phone'); } }
hasOne メソッド 最初のパラメータは関連付けられるモデルです。定義後、次の構文を使用して関連付けられた属性をクエリできます。
$phone = User::find(1)->phone;
Eloquent は関連付けられた外部キーがモデル名に基づいていると想定します。 Phone モデルは自動的に user_id フィールドを外部キーとして使用します。2 番目のパラメーターと 3 番目のパラメーターを使用して
return $this->hasOne('App\Phone', 'foreign_key');return $this->hasOne('App\Phone', 'foreign_key', 'local_key');
上記のモデルを定義した後、User モデルを使用して取得することができますもちろん、Phone モデルを通じて対応するユーザーを取得することもできます。これは、belongsTo メソッドを使用します
<?phpnamespace App;use Illuminate\Database\Eloquent\Model;class Phone extends Model{ /** * Get the user that owns the phone. */ public function user() { return $this->belongsTo('App\User'); // return $this->belongsTo('App\User', 'foreign_key'); // return $this->belongsTo('App\User', 'foreign_key', 'other_key'); } }
<?phpnamespace App;use Illuminate\Database\Eloquent\Model;class Post extends Model{ /** * Get the comments for the blog post. */ public function comments() { return $this->hasMany('App\Comment'); } }
$comments = App\Post::find(1)->comments; foreach ($comments as $comment) { //} $comments = App\Post::find(1)->comments()->where('title', 'foo')->first();
$comment = App\Comment::find(1); echo $comment->post->title;
<?phpnamespace App;use Illuminate\Database\Eloquent\Model;class User extends Model{ /** * The roles that belong to the user. */ public function roles() { // 指定关联表 // return $this->belongsToMany('App\Role', 'role_user'); // 指定关联表,关联字段 // return $this->belongsToMany('App\Role', 'role_user', 'user_id', 'role_id'); return $this->belongsToMany('App\Role'); } }
user = App\User::find(1); foreach ($user->roles as $role) { //}$roles = App\User::find(1)->roles()->orderBy('name')->get();
<?phpnamespace App;use Illuminate\Database\Eloquent\Model;class Role extends Model{ /** * The users that belong to the role. */ public function users() { return $this->belongsToMany('App\User'); } }
$user = App\User::find(1); foreach ($user->roles as $role) { echo $role->pivot->created_at; }
オブジェクトを介してアクセスできることに注意してください。中間テーブルに追加の属性が含まれている場合は、関連付けを指定するときに withPivot メソッドを使用して列名を明示的に指定する必要があります
return $this->belongsToMany('App\Role')->withPivot('column1', 'column2');
countries id - integer name - stringusers id - integer country_id - integer name - stringposts id - integer user_id - integer title - string
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', 'country_id', 'user_id'); return $this->hasManyThrough('App\Post', 'App\User'); } }
があります。メソッド hasManyThrough の最初のパラメータは、アクセスしたいモデルの名前であり、2 番目のパラメータは中間モデル名です。 。
HasManyThrough hasManyThrough( string $related, string $through, string|null $firstKey = null, string|null $secondKey = null, string|null $localKey = null)
ポリモーフィック リレーション (ポリモーフィック リレーション)
テーブル構造は次のとおりです
posts id - integer title - string body - textcomments id - integer post_id - integer body - textlikes id - integer likeable_id - integer likeable_type - string
ご覧のとおり、likes テーブルの likeable_type フィールドを使用して、レコードが投稿またはコメントを気に入っているかどうかを判断します。テーブル構造が整ったら、次は、 model
<?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 product'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'); } }
デフォルトでは、likeable_type タイプは、ここでは AppPost や AppComment など、関連付けられたモデルの完全な名前です。
通常、関連付けられたテーブル名を識別するためにカスタム値を使用することがあります。そのため、プロジェクトのサービスプロバイダーオブジェクトのブートメソッドで関連付けをカスタマイズする必要があります。
use Illuminate\Database\Eloquent\Relations\Relation;Relation::morphMap([ 'posts' => App\Post::class, 'likes' => App\Like::class,]);
AppServiceProvider
投稿のすべての「いいね」にアクセスします
$post = App\Post::find(1); foreach ($post->likes as $like) { //}
$like = App\Like::find(1); $likeable = $like->likeable;
上記の例では、返された likeable はレコードのタイプに応じて投稿またはコメントを返します。
多対多のポリモーフィックな関連付け
多対多の関連付けは、morphToMany と morphedByMany メソッドを使用します。ここではこれ以上ナンセンスではありません
Eloquent では、すべての関係は関数を使用して
定義されており/** * Get all of the posts for the user. */public function posts() { return $this->hasMany('App\Post'); }
次のように関連付けをクエリし、追加の 制約を追加できます
$user = App\User::find(1);$user->posts()->where('active', 1)->get();
関連する属性に制約を追加する必要がない場合は、上記の例のように、モデル属性アクセスとして直接使用できます。次のメソッドを使用してユーザーの投稿にアクセスできます 动态的属性都是延迟加载的,它们只有在被访问的时候才会去查询数据库,与之对应的是预加载,预加载可以使用关联查询出所有数据,减少执行sql的数量。 使用has方法可以基于关系的存在性返回结果 如果需要更加强大的功能,可以使用whereHas和orWhereHas方法,把where条件放到has语句中。 在访问Eloquent模型的时候,默认情况下所有的关联关系都是延迟加载的,在使用的时候才会开始加载,这就造成了需要执行大量的sql的问题,使用预加载功能可以使用关联查询出所有结果 接下来我们检索所有的书和他们的作者 上面的查询将会执行一个查询查询出所有的书,然后在遍历的时候再执行N个查询查询出作者信息,显然这样做是非常低效的,幸好我们还有预加载功能,可以将这N+1个查询减少到2个查询,在查询的时候,可以使用with方法指定哪个关系需要预加载。 对于该操作,会执行下列两个sql 预加载多个关系 嵌套的预加载 延迟预加载# 有时候,在上级模型已经检索出来之后,可能会需要预加载关联数据,可以使用load方法 保存单个关联模型 多对多关联可以为save的第二个参数指定关联表中的属性 上述代码会更新中间表的expires字段。 使用create方法与save方法的不同在于它是使用数组的形式创建关联模型的 更新belongsTo关系的时候,可以使用associate方法,该方法会设置子模型的外键 要移除belongsTo关系的话,使用dissociate方法 中间表查询条件# 当查询时需要对使用中间表作为查询条件时,可以使用 Attaching / Detaching# attach和detach方法支持数组参数,同时添加和移除多个 使用updateExistingPivot方法更新中间表 同步中间表(同步关联关系)# 使用sync方法,可以指定两个模型之间只存在指定的关联关系 上述两个方法都会让用户只存在1,2,3三个角色,如果用户之前存在其他角色,则会被删除。 更新父模型的时间戳# 假设场景如下,我们为一个帖子增加了一个新的评论,我们希望这个时候帖子的更新时间会相应的改变,这种行为在Eloquent中是非常容易实现的。 在子模型中使用$touches属性实现该功能 现在,更新评论的时候,帖子的updated_at字段也会被更新 以上がLaravel フレームワーク - EloquentORM の高度な部分の詳細な紹介の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。$user = App\User::find(1);foreach ($user->posts as $post) { //}
查询关系存在性
// 检索至少有一个评论的所有帖子...$posts = App\Post::has('comments')->get();
// Retrieve all posts that have three or more comments...$posts = Post::has('comments', '>=', 3)->get();
// Retrieve all posts that have at least one comment with votes...$posts = Post::has('comments.votes')->get();
// 检索所有至少存在一个匹配foo%的评论的帖子$posts = Post::whereHas('comments', function ($query) {
$query->where('content', 'like', 'foo%');
})->get();
预加载
<?phpnamespace App;use Illuminate\Database\Eloquent\Model;class Book extends Model{
/**
* Get the author that wrote the book.
*/
public function author()
{
return $this->belongsTo('App\Author');
}
}
$books = App\Book::all();
foreach ($books as $book) {
echo $book->author->name;
}
$books = App\Book::with('author')->get();
foreach ($books as $book) {
echo $book->author->name;
}
select * from books
select * from authors where id in (1, 2, 3, 4, 5, ...)
$books = App\Book::with('author', 'publisher')->get();
$books = App\Book::with('author.contacts')->get();
带约束的预加载
$users = App\User::with(['posts' => function ($query) {
$query->where('title', 'like', '%first%');
}])->get();$users = App\User::with(['posts' => function ($query) {
$query->orderBy('created_at', 'desc');
}])->get();
$books = App\Book::all();if ($someCondition) { $books->load('author', 'publisher');
}$books->load(['author' => function ($query) {
$query->orderBy('published_date', 'asc');
}]);
关联模型插入
save方法
$comment = new App\Comment(['message' => 'A new comment.']);
$post = App\Post::find(1);$post->comments()->save($comment);
保存多个关联模型
$post = App\Post::find(1);
$post->comments()->saveMany([
new App\Comment(['message' => 'A new comment.']),
new App\Comment(['message' => 'Another comment.']),
]);
save方法和多对多关联
App\User::find(1)->roles()->save($role, ['expires' => $expires]);
create方法
$post = App\Post::find(1);$comment = $post->comments()->create([
'message' => 'A new comment.',]);
更新 “Belongs To” 关系
$account = App\Account::find(10);
$user->account()->associate($account);
$user->save();
$user->account()->dissociate();$user->save();
Many to Many 关系
wherePivot
, wherePivotIn
,orWherePivot
,orWherePivotIn
添加查询条件。$enterprise->with(['favorites' => function($query) {
$query->wherePivot('enterprise_id', '=', 12)->select('id');
}]);
$user = App\User::find(1);
// 为用户添加角色
$user->roles()->attach($roleId);
// 为用户添加角色,更新中间表的expires字段
$user->roles()->attach($roleId, ['expires' => $expires]);
// 移除用户的单个角色
$user->roles()->detach($roleId);
// 移除用户的所有角色
$user->roles()->detach();
$user = App\User::find(1);
$user->roles()->detach([1, 2, 3]);
$user->roles()->attach([1 => ['expires' => $expires], 2, 3]);
更新中间表(关联表)字段
$user = App\User::find(1);$user->roles()->updateExistingPivot($roleId, $attributes);
$user->roles()->sync([1, 2, 3]);
$user->roles()->sync([1 => ['expires' => true], 2, 3]);
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;class Comment extends Model{ /**
* All of the relationships to be touched.
*
* @var array
*/
protected $touches = ['post']; /**
* Get the post that the comment belongs to.
*/
public function post()
{ return $this->belongsTo('App\Post');
}
}
$comment = App\Comment::find(1);$comment->text = 'Edit to this comment!';$comment->save();