きょうはLaravelのhasManyな関係について、解説しますね!
laravelでbelongsToを設定する方法を説明します!
いわゆる1対多をどうやって実装するのかという話しですね。
さらに、select, insertなどの検索と保存についても説明しておきます。
laravelで1対多(belongsTo)を実装する
まずはモデルファイルの設定を。
Userモデルと、Postモデルで説明します。
User hasMany Postな1対多の関係です。
から説明しますね。
※migrationファイルは作れるものとして説明します。
またmigrationファイルでforegin keyを設定しなくとも、この実装で1対多の実装ができます。
まあ、普通は外部キー制約つるのが普通ですけどね。
User.php
<?php namespace App; use Illuminate\Notifications\Notifiable; use Illuminate\Contracts\Auth\MustVerifyEmail as MustVerifyEmail; use Illuminate\Foundation\Auth\User as Authenticatable; class User extends Authenticatable implements MustVerifyEmail { use Notifiable; /** * The attributes that are mass assignable. * * @var array */ protected $fillable = [ 'name', 'email', 'password', 'avatar', ]; /** * The attributes that should be hidden for arrays. * * @var array */ protected $hidden = [ 'password', 'remember_token', ]; /** * The attributes that should be cast to native types. * * @var array */ protected $casts = [ 'email_verified_at' => 'datetime', ]; public function posts() { return $this->hasMany('App\Post'); } }
そんでPost.php
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Post extends Model { protected $fillable = [ 'contentl', 'user_id' ]; // リレーション public function user() { return $this->belongsTo('App\User'); } }
UserはPostをhasManyな関係です。なのでモデルにこう書きます。
postsと複数形にするのが一般的です。(たぶん単数形でも大丈夫なはず)
userは複数のpostを持っているのでpostsにするわけですね。
public function posts() { return $this->hasMany('App\Post'); }
これはpostsテーブルにuser_idという名前のカラム(外部キー)が存在する前提です。
もしこれが別の名前だったら、第二引数にreturn $this->hasMany(‘App\Post’, ‘another_user_id’); というようにカラム名を指定します。
逆に、Postモデル側だとこうですね。
メソッド名が単数系なのに注目。postが持っているのは1つの親(user)なので単数形。
public function user() { return $this->belongsTo('App\User'); }
belongsTo, hasManyなデータにアクセスする方法|select
controllerファイルでbelongsTo, hasManyなデータを安家方法です。
モデルファイルにpostsメソッドを書いてあると、postsプロパティにアクセスできます。
use App\User;
これをお忘れなく。
$user = User::find(1) $user->posts foreach($user->posts as $post){ $post->content }
SQLでいうとこんな検索をします。
SELECT posts.* FROM posts WHERE posts.user_id = 1
postsテーブルのcontentカラムにアクセスするときは上記のようにforeachしてカラム名のメンバ変数にアクセスします。
簡単ですね!
続いてPostモデルからその所有者であるuserを取得する場合
user App\User; を忘れずに。
$post = Post::find(1); $post->user->name;
Postモデルにuserメソッドを実装しましたよね?そうするとuserというメンバ変数でアクセスできるみたいです。
簡単ですね!
続いてinser系です。
belongsTo, hasManyなデータをDBに保存する方法|insert
こんな感じです。
Auth::user()->posts()->create($request->all());
Auth::user()はApp\Userのインスタンスを返します。モデルですね。
それでAuth::user()->posts()はこのインスタンスを返します。
Illuminate\Database\Eloquent\Relations\HasMany
→Laravel5.8公式ドキュメント
はい、ここで間違いやすい注意点です。
postsに()がない下記だとCollectionインスタンスを返します。User::findとかで取得できるアレです。
Auth::user()->posts
これはuserがhasManyなpostをすべて取得するわけです。
今回はcreateしたいので、そうではなくて Auth::user()->posts()にするのです。
公式ドキュメントを見るとわかるのですが、createメソッドがありますね。
引数は配列を取りますので、$request->all()
で配列を渡してあげます。
ちなみに、postを1つではなく、複数一気に保存したい場合にはcreateMany
メソッドを使いましょう。
引数を、保存したい値の配列を、さらに配列で囲みます。
Auth::user()->posts()->createMany([$request->all()]);
こんな感じ。簡単ですね!
今日のところはこんな感じです!
最後に!
あと、エンジニアの年収を上げる方法やフリーの営業法をツイートしてるんでフォローしてくださいっ!!
今はRubyの仕事をしてます。
働いてるのは週に2日だけですが、それでも年収は400万近くまでいきます。 プログラミングは安定して、そこそこの金額を稼げるいい仕事です 実務経験が5年くらいあれば誰でもできるので駆け出しエンジニアさんも夢があるんじゃないかと。 — ぱんだ@週2日エンジニア/フリーランス (@panda_program_) March 17, 2019
フォローは↓からですよ!
Follow @panda_program_