为啥我在 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 中的 Associate()

为啥我在 laravel 中运行测试时收到“CSRF 令牌不匹配”?

当我使用 ajax 发布请求时,为啥在我的 live laravel 项目中显示 404 和 405

为啥我在 Laravel 中收到“Route [/login] not defined 错误”?

为啥我在 laravel 到 fontawesome 的路径错误?

为啥我在作曲家安装后在 Laravel 中收到 500 服务器错误 [关闭]