開発ブログ

株式会社Nextatのスタッフがお送りする技術コラムメインのブログ。

電話でのお問合わせ 075-744-6842 ([月]-[金] 10:00〜17:00)

  1. top >
  2. 開発ブログ >
  3. PHP >
  4. Laravel >
  5. Laravel5.5 リレーションしているデータの保存方法(1対1 1対多 多対多)

Laravel5.5 リレーションしているデータの保存方法(1対1 1対多 多対多)

こんにちは。
ニシザワです。

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の非常によいところです。
ぜひ、積極的に使っていってください。
TOPに戻る