サーチ…
関係の照会
Eloquentでは、以下に示すように、定義された関係についても照会することができます。
User::whereHas('articles', function (Builder $query) {
$query->where('published', '!=', true);
})->get();
この場合、関係メソッド名はarticles
でなければなりません。クロージャーに渡される引数は、関連するモデルのクエリビルダです。ここでは、他のクエリを使用できます。
Eager Loading
ユーザーモデルが記事モデルとの関係を持ち、関連記事を熱心に読み込みたいとします。これは、ユーザーを検索するときにユーザーの記事が読み込まれることを意味します。
articles
は、Userモデルの関係名(メソッド)です。
User::with('articles')->get();
複数の関係がある場合。例えば記事や投稿など。
User::with('articles','posts')->get();
ネストされた関係を選択する
User::with('posts.comments')->get();
複数のネストされた関係を呼び出す
User::with('posts.comments.likes')->get()
関連モデルを挿入する
Comment
付きのhasMany
関係を持つPost
モデルがあるとします。次のようにして、投稿に関連するComment
オブジェクトを挿入することができます:
$post = Post::find(1);
$commentToAdd = new Comment(['message' => 'This is a comment.']);
$post->comments()->save($commentToAdd);
saveMany
関数を使用すると、複数のモデルを同時に保存できます。
$post = Post::find(1);
$post->comments()->saveMany([
new Comment(['message' => 'This a new comment']),
new Comment(['message' => 'Me too!']),
new Comment(['message' => 'Eloquent is awesome!'])
]);
代わりに、Eloquentモデルインスタンスの代わりにプレーンなPHP配列を受け付けるcreate
メソッドもあります。
$post = Post::find(1);
$post->comments()->create([
'message' => 'This is a new comment message'
]);
前書き
Eloquent関係はEloquentモデルクラスの関数として定義されています。 Eloquentモデル自体のように、関係は強力なクエリビルダとしても機能するため、関数としてのリレーションシップを定義することで強力なメソッド連鎖とクエリ機能が提供されます。たとえば、この投稿の関係に制約を追加することができます。
$user->posts()->where('active', 1)->get();
関係タイプ
1対多数
各投稿に1つ以上のコメントがあり、各コメントはただ1つの投稿に属するとします。
コメントテーブルはpost_id
を持つようにpost_id
ます。この場合の関係は次のようになります。
ポストモデル
public function comments()
{
return $this->belongsTo(Post::class);
}
外部キーがpost_id
以外のpost_id
、例えば外部キーはexample_post_id
です。
public function comments()
{
return $this->belongsTo(Post::class, 'example_post_id');
}
ローカル鍵がid
以外の場合、例えばローカル鍵がother_id
public function comments()
{
return $this->belongsTo(Post::class, 'example_post_id', 'other_id');
}
コメントモデル
1対多数の逆を定義する
public function post()
{
return $this->hasMany(Comment::class);
}
1対1
2つのモデルを関連付ける方法(例: User
モデルとPhone
モデル)
App\User
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* Get the phone record associated with the user.
*/
public function phone()
{
return $this->hasOne('Phone::class', 'foreign_key', 'local_key');
}
}
App\Phone
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Phone extends Model
{
/**
* Get the user that owns the phone.
*/
public function user()
{
return $this->belongsTo('User::class', 'foreign_key', 'local_key');
}
}
foreign_key
:デフォルトでは、Eloquentはこの値をother_model_name_id
(この場合はuser_id
とphone_id
)とphone_id
、そうでない場合は変更します。
local_key
:デフォルトでは、Eloquentはこの値をid
(現在のモデルの主キー)とみなし、そうでない場合は変更します。
データベースがlaravel標準に従って名前をファイルした場合、関係宣言に外部キーとローカルキーを指定する必要はありません
説明
多対多
役割と権限があるとします。各役割は多くの権限に属し、各権限は多くの役割に属します。 3つのテーブルがあります。 2つのモデルと1つのピボットテーブル。 roles
、 users
、およびpermission_role
テーブル
ロールモデル
public function permissions()
{
return $this->belongsToMany(Permission::class);
}
許可モデル
public function roles()
{
return $this->belongsToMany(Roles::class);
}
注:1
ピボット・テーブルに異なるテーブル名を使用しながら、次のことを検討してください。
eloquentがピボット・キー名を構築するためにアルファベット順を使用するrole_permission
、 permission_role
代わりにrole_permission
を使用するとします。ピボットテーブル名を次のように2番目のパラメータとして渡す必要があります。
ロールモデル
public function permissions()
{
return $this->belongsToMany(Permission::class, 'role_permission');
}
許可モデル
public function roles()
{
return $this->belongsToMany(Roles::class, 'role_permission');
}
注:2
ピボット・テーブルで異なるキー名を使用している間は、
Eloquentは、3番目と4番目のパラメータとしてキーが渡されないと、 _id
持つ特異なテーブル名になると仮定します。ピボットはrole_id
とpermission_id
各フィールドを持っていると仮定します。これら以外のキーを使用する場合は、3番目と4番目のパラメーターとして渡す必要があります。
あれば言うことができますother_role_id
の代わりにrole_id
とother_permission_id
の代わりpermission_id
使用されるべきです。それは次のようになります。
ロールモデル
public function permissions()
{
return $this->belongsToMany(Permission::class, 'role_permission', 'other_role_id', 'other_permission_id');
}
許可モデル
public function roles()
{
return $this->belongsToMany(Roles::class, 'role_permission', 'other_permission_id', 'other_role_id');
}
多型
多態性の関係は、モデルが単一の関連付けで複数の他のモデルに属することを可能にする。良い例はイメージであり、ユーザーとプロダクトの両方がイメージを持つことができます。テーブルの構造は次のようになります。
user
id - integer
name - string
email - string
product
id - integer
title - string
SKU - string
image
id - integer
url - string
imageable_id - integer
imageable_type - string
見るべき重要な列は画像テーブルにあります。 imageable_id
列にはユーザーまたは製品のID値が含まれ、 imageable_type
列には所有モデルのクラス名が含まれます。モデルでは、次のように関係を設定します。
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Image extends Model
{
/**
* Get all of the owning imageable models.
*/
public function imageable()
{
return $this->morphTo();
}
}
class User extends Model
{
/**
* Get all of the user's images.
*/
public function images()
{
return $this->morphMany('Image::class', 'imageable');
}
}
class Product extends Model
{
/**
* Get all of the product's images.
*/
public function images()
{
return $this->morphMany('Image::class', 'imageable');
}
}
また、多態性モデルから多態性関係の所有者を取得するには、 morphTo
の呼び出しを実行するメソッドの名前にアクセスしmorphTo
。私たちの場合、それはイメージモデル上のimageable
メソッドです。そこで、そのメソッドに動的プロパティとしてアクセスします
$image = App\Image::find(1);
$imageable = $image->imageable;
このimageable
は、ユーザーまたはプロダクトのいずれかを返します。
多対多
役割と権限があるとします。各役割は多くの権限に属し、各権限は多くの役割に属します。 3つのテーブルがあります。 2つのモデルと1つのピボットテーブル。 roles
、 users
、およびpermission_role
テーブル
ロールモデル
public function permissions()
{
return $this->belongsToMany(Permission::class);
}
許可モデル
public function roles()
{
return $this->belongsToMany(Roles::class);
}
注:1
ピボット・テーブルに異なるテーブル名を使用しながら、次のことを検討してください。
eloquentがピボット・キー名を構築するためにアルファベット順を使用するrole_permission
、 permission_role
代わりにrole_permission
を使用するとします。ピボットテーブル名を次のように2番目のパラメータとして渡す必要があります。
ロールモデル
public function permissions()
{
return $this->belongsToMany(Permission::class, 'role_permission');
}
許可モデル
public function roles()
{
return $this->belongsToMany(Roles::class, 'role_permission');
}
注:2
ピボット・テーブルで異なるキー名を使用している間は、
Eloquentは、3番目と4番目のパラメータとしてキーが渡されないと、 _id
持つ特異なテーブル名になると仮定します。ピボットはrole_id
とpermission_id
各フィールドを持っていると仮定します。これら以外のキーを使用する場合は、3番目と4番目のパラメーターとして渡す必要があります。
あれば言うことができますother_role_id
の代わりにrole_id
とother_permission_id
の代わりpermission_id
使用されるべきです。それは次のようになります。
ロールモデル
public function permissions()
{
return $this->belongsToMany(Permission::class, 'role_permission', 'other_role_id', 'other_permission_id');
}
許可モデル
public function roles()
{
return $this->belongsToMany(Roles::class, 'role_permission', 'other_permission_id', 'other_role_id');
}
withPivot()を使用して中間テーブルにアクセスする
ピボットテーブルに3番目の列 ' permission_assigned_date 'があるとします。デフォルトでは、モデルキーのみがピボットオブジェクトに表示されます。クエリ結果でこの列を取得するには、withPivot()関数で名前を追加する必要があります。
public function permissions()
{
return $this->belongsToMany(Permission::class, 'role_permission', 'other_role_id', 'other_permission_id')->withPivot('permission_assigned_date');
}
アタッチ/デタッチ
また、Eloquentは、関連モデルでの作業をより便利にするための、いくつかのヘルパーメソッドを追加しています。たとえば、ユーザーが多くの役割を持つことができ、役割に多くのアクセス許可を持たせることができます。モデルを結合する中間テーブルにレコードを挿入して、権限にロールを添付するには、attachメソッドを使用します。
$role= App\Role::find(1);
$role->permissions()->attach($permissionId);
モデルにリレーションシップを追加するときに、中間テーブルに挿入する追加データの配列を渡すこともできます。
$rol->roles()->attach($permissionId, ['permission_assigned_date' => $date]);
同様に、ロールに対して特定の権限を削除するには、detach関数を使用します
$role= App\Role::find(1);
//will remove permission 1,2,3 against role 1
$role->permissions()->detach([1, 2, 3]);
同期団体
また、syncメソッドを使用して多対多の関連付けを構築することもできます。 syncメソッドはIDの配列を受け取り、中間テーブルに配置します。指定された配列にないIDは中間テーブルから削除されます。したがって、この操作が完了すると、指定された配列のIDのみが中間テーブルに存在します。
//will keep permission id's 1,2,3 against Role id 1
$role= App\Role::find(1)
$role->permissions()->sync([1, 2, 3]);