🍣
Laravel 1対多 リレーション時、Modelの命名規則
以下のようなデータベースを作っていたのですが、Blog側からUserが呼べず頭を抱えました。結論から言うとModel内のメソッドに命名規則があるということです。なにが問題だったか記述していきます。
動作環境
PHP 8.2
Laravel 10
マイグレーション
usersのマイグレーションは初期設定のままです。
usersのマイグレーション
public function up(): void
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
blogsはusersの外部キーを設定します。
blogsのマイグレーション
public function up(): void
{
Schema::create('blogs', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('content');
$table->foreignId('user_id')->constrained()->onDelete('cascade');
$table->timestamps();
});
}
リレーション
リレーションするには、ModelのUserとBlogに、メソッドを追加しなければなりません。
Userモデル
app/Models/User.php
use Illuminate\Database\Eloquent\Relations\HasMany;
public function blogs(): HasMany
{
return $this->hasMany(Blog::class);
}
Blogモデル
Blogにメソッドを記述する際、usersと複数形を記述していますが、これが原因です。この状態でいくらUserを呼び出そうとしても、nullしか返してきません。
app/Models/Blog.php
use Illuminate\Database\Eloquent\Relations\BelongsTo;
public function users(): BelongsTo
{
return $this->belongsTo(User::class);
}
解決方法
1対多なので、Blog側から呼び出すUserは単数形。ということで、usersではダメです。このメソッドはuserとして単数形にすれば、Blog側からUserを呼び出すことができます。
app/Models/Blog.php
use Illuminate\Database\Eloquent\Relations\BelongsTo;
- public function users(): BelongsTo
+ public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
まとめ
リレーションするためのメソッドにも命名規則があるのですね。テーブル名がusersだから、メソッド名もusersでいいや、と思ってメソッドを書いて、痛い目を見ました。今後は、Laravelの命名規則もしっかり合わせていきます。
参考記事
Discussion