Laravel5.5 リレーションしているデータの保存方法(1対1 1対多 多対多)
こんにちは。
ニシザワです。
Laravelでリレーションさせているデータ
・1対1
・1対多
・多対多
があると思います。
これを関連テーブルと一緒に保存する方法を今回は紹介します。
※関連モデルにfillableを設定するのを忘れずに。
複数のテーブルを更新する場合はトランザクションで囲むのもポイントです。
※関連モデルにfillableを設定するのを忘れずに。
コントローラー側
formで投げるデータを整形するだけで、コントローラー側がすごくスッキリしてきますのでおすすめです。
相手側が多の関係になるといちいちnewして外部キー設定して、保存するみたいなことをLaravelが用意したメソッドで解決できるのはLaravelの非常によいところです。
ぜひ、積極的に使っていってください。
ニシザワです。
Laravelでリレーションさせているデータ
・1対1
・1対多
・多対多
があると思います。
これを関連テーブルと一緒に保存する方法を今回は紹介します。
1対1の例
モデルは下記※関連モデルにfillableを設定するのを忘れずに。
class User extends Model
{
protected $fillable = [
'name',
'email'
]
/**
* ユーザーに関連する電話レコードを取得
*/
public function phone() : HasOne
{
return $this->hasOne(Phone::class);
}
}
リクエストの中はこのような形になっているとしましょう。
[
'user' => [
'name' => 'hoge',
'email' => 'hoge@hoge.com'
],
'phone' => [
'number' => '075-744-6842'
]
]
コントローラー側
public function store(Request $request) : RedirectResponse
{
DB::beginTransaction();
try{
$user = new User($request->get('user', []));
$user->save()
$user->phone()->create($request->get('phone', []));
}catch(Exception $e){
DB::rollback();
return back()->withInput();
}
DB::commit();
return redirect('/');
}
自動的にリレーションさせた先にuser_idがセットされるので便利です。複数のテーブルを更新する場合はトランザクションで囲むのもポイントです。
1対多の例
モデルは下記※関連モデルにfillableを設定するのを忘れずに。
class Post extends Model
{
protected $fillable = [
'title',
'content'
]
/**
* ブログポストのコメントを取得
*/
public function comments() : HasMany
{
return $this->hasMany(Comment::class);
}
}
リクエストの中はこのような形になっているとしましょう。
[
'post' => [
'title' => '本日の天気',
'content' => '天気は晴れ'
],
'comments' => [
[
'content' => '晴れですか!'
],
[
'content' => '明日テストやから台風来て・・・'
]
]
]
コントローラー側
public function store(Request $request) : RedirectResponse
{
DB::beginTransaction();
try{
$post = new Post($request->get('post', []));
$post->save()
$post->comments()->createMany($request->get('comments', []));
}catch(Exception $e){
DB::rollback();
return back()->withInput();
}
DB::commit();
return redirect('/');
}
多対多の例
モデルは下記class User extends Model
{
/**
* userに所属する役目を取得
*/
public function roles() : BelongsToMany
{
return $this->belongsToMany(Role::class);
}
}
リクエストの中はこのような形になっているとしましょう。
[
'user' => [
'name' => 'hoge',
'email' => 'hoge@hoge.com'
],
'roles' => [
1,2,3,4
]
]
rolesの中はrolesのIDが入っています。コントローラー側
public function store(Request $request) : RedirectResponse
{
DB::beginTransaction();
try{
$user = new User($request->get('user', []));
$user->save()
$user->roles()->sync($request->get('roles', []));
}catch(Exception $e){
DB::rollback();
return back()->withInput();
}
DB::commit();
return redirect('/');
}
まとめ
決まった形でPOSTしてあげれば、このまま使えます。formで投げるデータを整形するだけで、コントローラー側がすごくスッキリしてきますのでおすすめです。
相手側が多の関係になるといちいちnewして外部キー設定して、保存するみたいなことをLaravelが用意したメソッドで解決できるのはLaravelの非常によいところです。
ぜひ、積極的に使っていってください。