こんにちは。Laravelのリレーション毎回間違えるマンです。
sqlのjoinと同様に結合元のテーブルのキーを毎回左側に書いてしまう癖があります。
*[注意]joinは特に順番は決まってないが一般的に結合元テーブルを左側に書くことが多い気がする。
class User extends Model
{
public function posts()
{
return $this->hasMany(Post::class, 'id', 'user_id');
}
// こんな書き方をする時もある。
public function posts()
{
return $this->hasMany('App\Models\Post', 'id', 'user_id');
}
}
これらはエラーとなります。ひっくり返せば治るので深く考えたことがなかったのですが、たまたま見た記事に答えが書いてあったので、忘備録として本記事を書きます。
🔽分かりやすい記事
https://qiita.com/saya1001kirinn/items/69e2146691101f92d57b
引用の引用ですがこれが真理
常に第2引数が Foreign Key で,第3引数が Local Key です。
先ほどの例で言うと
Foreign Key: user_id
Local Key: id
となるので、こうなる。
class User extends Model
{
public function posts()
{
return $this->hasMany(Post::class, 'user_id', 'id');
}
}
belongsToも同様に外部キー、ローカルキーの順番
class Post extends Model
{
public function user()
{
return $this->belongsTo(User::class, 'user_id', 'id');
}
}
リーダブルにも書いてあったのです。ちゃんと読もう。自戒。
https://readouble.com/laravel/7.x/ja/eloquent-relationships.html
ちなみに中間テーブル作ってbelongsToManyする場合
これは当初勘違いしてたsqlのjoinと同じ考え方でいける
第一引数:結合先モデル
第二引数:中間テーブル名
第三引数:中間テーブル・呼び出し元の外部キー
第四引数:中間テーブル・呼び出され側の外部キー
第3引数はリレーションを定義しているモデルの外部キー名で、一方の第4引数には結合するモデルの外部キー名を渡します。
UserとPostの中間テーブルtagsを想定
class User extends Model
{
public function posts()
{
return $this->belongsToMany(Post::class, 'tags', 'user_id', 'post_id');
}
}
class Post extends Model
{
public function users()
{
return $this->belongsToMany(User::class, 'tags', 'post_id', 'user_id');
}
}