为啥我在 Laravel 中简单的 belongsTo 关系不起作用?
Posted
技术标签:
【中文标题】为啥我在 Laravel 中简单的 belongsTo 关系不起作用?【英文标题】:Why does my simple belongsTo ralationship in Laravel not working?为什么我在 Laravel 中简单的 belongsTo 关系不起作用? 【发布时间】:2021-06-01 02:37:03 【问题描述】:我有一个用户迁移如下:
Schema::create('users', function (Blueprint $table)
$table->id();
$table->string('name')->nullable();
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
);
还有一个 BlogPosts 迁移如下:
Schema::create('blog_posts', function (Blueprint $table)
$table->id();
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
$table->string('title')->unique();
$table->string('image');
$table->text('text');
$table->timestamps();
);
他们每个人都有一个模型(博客帖子和用户)
在 BlogPost 模型上,我有以下内容:
public function getUser()
return $this->belongsTo(User::class);
我在数据库中添加了一些测试数据,如下所示:
用户表:
ID:1,邮箱:test@test.com,密码:hashed
blog_post 表:
ID:1,title:title,image:/image.jpg,text:一些文本,user_id:1
现在在修补程序中,我执行以下操作:
$var = \App\Models\BlogPost::find(1);
$var->getUser(); //Outputs: null
如果我将 getUser 修改为:
public function getUser()
return $this->belongsTo(User::class)->toSql();
tinker 的输出是:
从
users
中选择*,其中users
.id
为空
我在这里做错了什么?,我错过了什么吗?
【问题讨论】:
您是否在blog_post
表格行中添加了user_id
值?
是的,抱歉,打错了。我已经改正了
尝试将此添加到您的博客帖子迁移中,然后删除 ->constrained()->cascadeOnDelete();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$var->getUser
,或$var->getUser()->first()
。如果您将您的关系命名为user
,您可能会更好,因此您可以使用$var->user
或$var->user()->first()
。作为旁注,当您使用()
时,它是一个查询,直到您调用->first()
,然后它是一个模型实例或null
。如果不使用()
,则会在后台自动调用->first()
。
@MiqayelSrapionyan 给出相同的结果:(
【参考方案1】:
澄清一下,当你调用()
的关系时,你有一个Builder
类的实例,它允许你链接方法来执行额外的查询逻辑。例如:
$var = BlogPost::find(1);
$var->getUser();
如果您在php artisan tinker
中运行此代码,则输出不应为null
,而是Illuminate\Database\Eloquent\Relations\BelongsTo
的一个实例。预计您将 closure
传递给您的查询以实际执行它:
$var = BlogPost::find(1);
$var->getUser()->first();
这应该输出App\Models\User
的实例,或者,如果没有关联记录,则输出null
。
关系也提供快速访问属性,让您可以简单地执行以下操作:
$var = BlogPost::find(1);
$var->getUser;
当您省略 ()
时,适当的 closure
会在幕后自动应用。对于belongsTo()
,应用->first()
。
最后,建议以关联的模型命名您的关系。在这种情况下:
public function user()
return $this->belongsTo(User::class);
有几个原因。首先,public function getUser()
建议通过 getter 方法调用(就像您正在做的那样,通过 ->getUser()
),但是由于这可以作为属性调用(通过 ->getUser
),所以它是模棱两可的。其次,使用与模型相同的名称会自动应用外键。比较:
public function getUser()
return $this->belongsTo(User::class, 'user_id');
public function user()
return $this->belongsTo(User::class);
如果您使用getUser()
,则需要将user_id
作为外键传递(感谢r89human 捕捉到这个https://***.com/a/66441903/3965631)。如果你使用user()
,那么它是自动确定的。
【讨论】:
这是一个非常详细的回复。谢谢你。 没问题!user_id
参数很好;我将其添加到我的答案中,但也给了你信用:) 干杯!【参考方案2】:
使用此代码,它将正常工作。
public function getUser()
return $this->belongsTo( User::class, 'user_id' );
我们需要告诉 belongsTo 方法 user_id 是外键。
【讨论】:
以上是关于为啥我在 Laravel 中简单的 belongsTo 关系不起作用?的主要内容,如果未能解决你的问题,请参考以下文章
为啥我在 laravel 中运行测试时收到“CSRF 令牌不匹配”?
当我使用 ajax 发布请求时,为啥在我的 live laravel 项目中显示 404 和 405
为啥我在 Laravel 中收到“Route [/login] not defined 错误”?