【问题标题】:Laravel keeps pulling back all relations despite using `with()`尽管使用了 `with()`,Laravel 仍不断撤回所有关系
【发布时间】:2018-10-25 13:13:40
【问题描述】:

出于某种奇怪的原因,我的 Laravel 5.6 应用程序继续返回一个包含所有关系的用户对象。

我在Api/UserController的查询:

    public function show($user_id)
    {
        return User::with('meta', 'roles')->find($user_id);
    }

回应:

{
    "id": 1,
    "name": "Admin",
    "email": "admin@example.com",
    "company_id": 1,
    "meta": {
        "id": 1,
        "user_id": 1,
        "laptop": 0,
        "mobile": 0,
        "created_at": "2018-03-07 14:58:41",
        "updated_at": "2018-04-06 16:13:10"
    },
    "roles": [
        {
            "id": 2,
            "name": "admin",
            "label": "Admin",
            "permissions": null,
            "pivot": {
                "user_id": 1,
                "role_id": 2
            }
        }
    ],
    "company": {
        "id": 1,
        "name": "Company",
        "active": 1,
        "created_at": "2018-04-12 15:06:01",
        "updated_at": "2018-05-15 11:20:15",
        "is_max_user_limit_reached": true
    }
}

路线(routes/api.php内):

Route::group(['middleware' => 'auth:api'], function () {
    Route::resource('/users', 'Api\UserController', ['as' => 'api']);
});

用户模型:

        namespace App\Models;

        use App\Models\Role;

        class User extends Authenticatable implements HasMedia
        {
            use HasApiTokens, Notifiable, Billable, HasMediaTrait;

            protected $table = 'users';

            protected $fillable = ['name', 'email', 'password', 'is_active', 'company_id', 'stripe_id', 'card_brand', 'card_last_four', 'trial_ends_at'];

            protected $hidden = ['password', 'remember_token','card_brand', 'card_last_four'];

            protected $appends = ['extra', 'is_staff_only', 'first_four_training_sections', 'is_free_tier', 'is_agency_tier', 'is_team_tier', 'is_enterprise_tier'];


            public static $rules = [
                // create rules
                'name' => 'required',
                'email' => 'required|email|unique:users'
            ];


        public function meta()
        {
            return $this->hasOne(UserMeta::class);
        }


        public function company()
        {
            return $this->belongsTo(Company::class, 'company_id')->where('active', 1);
        }


        public function roles()
        {
            return $this->belongsToMany(Role::class);
        }


 public function getExtraAttribute()
    {
        return [
            'roles' => [
                'cpo' =>  (int)$this->hasRole('cpo'),
                'ap' =>  (int)$this->hasRole('ap'),
                'cao' => (int)$this->hasRole('cao'),
            ]
        ];
    }


    public function getIsStaffOnlyAttribute()
    {
        if($this->roles->count() == 1 && $this->hasRole('staff')) {
            return true;
        }
        return false;
    }

    public function getIsFreeTierAttribute()
    {
       return $this->company->subscription_tier == 0;
    }

    public function getIsAgencyTierAttribute()
    {
        return $this->company->subscription_tier == 1;
    }


    public function getIsTeamTierAttribute()
    {
        return $this->company->subscription_tier == 2;
    }


    public function getIsEnterpriseTierAttribute()
    {
        return $this->company->subscription_tier == 3;
    }



    public function getFirstFourTrainingSectionsAttribute() {
        return UserTrainingSection::where('user_id', $this->id)->orderBy('id')->take(4)->get();
    }

}

这是非常奇怪的行为。我只要求 rolesmeta 相关数据,但它总是返回用户模型上的每一个关系。

即使我尝试User::find($user_id);,它仍然会返回所有关系。

有人知道这里发生了什么吗?

我正在使用 Laravel 5.6 和 PHP 7.2

【问题讨论】:

  • 你能展示你的用户模型吗?
  • @aynber 当然,请参阅更新后的帖子。
  • 如果注释掉模型中的$appends 数组会发生什么?也许这些方法可以加载关系。
  • @Björn 天哪,你是对的。我注释掉了,现在它只返回我指定的metaroles。但是为什么这会影响查询呢?我仍然需要附加额外的列。
  • 您能否将在$appends 数组中附加的方法添加到上述问题中的用户模型中?

标签: php laravel laravel-5 orm relationship


【解决方案1】:

您可以使用$hidden 属性从响应中删除关系:

protected $hidden = ['company', ...];

您也可以暂时删除关系:

$user->addHidden('company');

【讨论】:

  • 但有时我可能想要company 关系,即如果我用User::with('meta', 'roles', 'company')->find($user_id); 调用它。我认为使用with() 的全部意义在于,您可以根据需要拉入关系。
  • 确实如此。但是 Laravel 将所有 loaded 关系添加到 JSON 响应中。在您的情况下,company 关系由 $appends 属性加载。我扩展了我的答案。
  • 您能否就扩展答案提供反馈?
  • 我只好接受加载所有关系,因为我不想用隐藏的属性到处乱跑。
猜你喜欢
  • 2017-02-17
  • 2022-06-10
  • 1970-01-01
  • 1970-01-01
  • 2016-12-20
  • 2017-07-06
  • 2017-12-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多