Laravel模型仅获得一个相关模型

时间:2020-10-22 08:37:20

标签: php laravel eloquent

我有一个与工作术语有关的用户模型,与诸如此类的服务有关:

 users      working_terms    services
 id    ->    user_id
             service_id  <-    id 
            active(1 or 0)

我在用户模型中创建了一个方法,以便检索像这样的有效工作期限的服务

public function service()
    {
        return $this
            ->belongsToMany(Service::class,'working_terms')
            ->where('active','=',1);

    }

问题是我必须像在视图$ user-> service [0]中那样使用它,我认为应该是$ user-> service 我能做什么 ?谢谢。

2 个答案:

答案 0 :(得分:0)

Laravel评估$user->service时,首先确定$user->service()的返回值是否是Illuminate\Database\Eloquent\Relation\Relation类的实例,如果不是,则给您错误。您的service()方法返回Illuminate\Database\Query\Builder而不是Relation,因此这就是您的代码段$user->service不返回您想要的服务模型的原因。

有关更多详细信息,请参见此链接; https://github.com/laravel/framework/blob/8.x/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php#L432

答案 1 :(得分:0)

belongsToMany关系返回一个Eloquent Collection,无论您是否提供where子句作为该关系的一部分。因此,您将需要使用first()来获取第一个(也是唯一一个?)记录。

在旁边的注释中,Laravel对数据透视表有一个命名约定(尽管我确定您有选择名称的理由)。

User.php

public function services()
{
  return $this->belongsToMany(Service::class)
              ->withTimestamps();
}

public function getActiveServiceAttribute()
{
  return $this->services()
              ->wherePivot('active', 1)
              ->first();
}

以上假设我遵循Laravel命名约定,其中usersservices表之间的数据透视表命名为service_user

create_service_user_table.php

public function up()
{
  Schema::create('service_user', function(Blueprint $table) {
    $table->id();
    $table->timestamps();

    $table->foreignId('user_id');
    $table->foreignId('service_id');
    $table->unsignedTinyInteger('active')->default(0);

    $table->foreign('user_id')->references('id')->on('users');
    $table->foreign('service_id')->references('id')->on('services');
  });
}

由于您未遵循Laravel命名约定,因此需要在belongsToMany函数中提供数据透视表的名称作为services()关系的第二个参数(或可能的更改)数据透视表名称并遵循约定)。

您现在应该可以执行以下操作:

// obtain a collection of all services the User has been associated with
User::find(1)->services

// obtain the currently active service for the User
User::find(1)->activeService