【问题标题】:Select specific columns from Eloquent relations从 Eloquent 关系中选择特定列
【发布时间】:2021-05-13 01:11:26
【问题描述】:

我的应用中有以下模型:

User.php

<?php namespace App\Models;

use Illuminate\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
use Kodeine\Acl\Traits\HasRole;

class User extends Model implements AuthenticatableContract, CanResetPasswordContract {

    use Authenticatable, CanResetPassword, HasRole;

    /**
     * The database table used by the model.
     *
     * @var stringSS
     */
    protected $table = 'users';

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = ['name', 'email', 'password', 'is_active'];

    /**
     * The attributes excluded from the model's JSON form.
     *
     * @var array
     */
    protected $hidden = ['password', 'remember_token'];

    public function customer_details()
    {
        return $this->hasOne('App\Models\CustomerDetails', 'user_id');
    }

}

CustomerDetails.php

<?php namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class CustomerDetails extends Model {

    protected $table = 'customer_details';
    protected $dates = ['created_at', 'updated_at', 'deleted_at'];
    protected $appends = ['full_name'];

    public function getFullNameAttribute()
    {
        return $this->attributes['first_name'] .' '. $this->attributes['last_name'];
    }

    public function user()
    {
        return $this->belongsTo('App\Models\User', 'user_id');
    }

    public function invoices() {
        return $this->hasMany('App\Models\Invoices', 'customer_id');
    }
}

现在我正在尝试运行以下查询:

$user = User::select('email', 'phone')->where('id', Auth::user()->id)->with('customer_details')->first();

现在我要做的是从我的 users 表和 first_nameemailphone 号码/strong>,last_name 来自我的 customer_details 表,但每当我尝试此操作时,它总是将 customer_details 返回为 null。此功能将仅在一个页面上使用,这意味着其他页面可能需要所有详细信息,但不是这个,因此我想创建一个单独的 Eloquent 关系来执行此操作。

【问题讨论】:

  • 在您的 User.php 文件中,您错过了指定 localKey 与外键比较:return $this-&gt;hasOne('App\Models\CustomerDetails', 'user_id'); 它应该是:return $this-&gt;hasOne('App\Models\CustomerDetails', 'user_id','id');

标签: laravel laravel-5


【解决方案1】:

您需要在您的选择中包含id,否则急切加载将无法匹配。我刚刚针对我自己的项目对此进行了测试并遇到了同样的问题,将id 添加到选择修复它。

$user = User::select('id', 'email', 'phone')->where('id', Auth::user()->id)->with('customer_details')->first();

为了进一步解释这一点,急切加载的工作原理是首先调用您的父级(在本例中,调用users),然后进行第二次调用,如SELECT * FROM customer_details WHERE customer_details.user_id IN (?),其中? 是用户ID 列表。然后它遍历第二次调用的结果并将它们附加到适当的用户对象。如果用户对象上没有 id,则在第二次调用或附加时没有可匹配的内容。

编辑

要从预先加载的表中选择特定列,您可以使用 here 中解释的闭包功能。因此,您使用关系名称作为键,并使用接收 Builder 对象作为值的闭包,如下所示:

$user = User::select('id', 'email', 'phone')
    ->where('id', Auth::user()->id)
    ->with('customer_details' => function (Builder $query) {
        $query->select('id', 'user_id', 'name', 'foo');
    })
    ->first();

注意你必须为两者选择关系列,否则 Laravel 不知道如何连接两者

【讨论】:

  • 谢谢你的工作 :) 我想问一下,我如何只从“customer_details”中选择特定的列?
  • @user3718908 请查看我刚刚对我的回答所做的编辑
  • 带有闭包的代码,有问题,它被红色下划线,我取出'Builder'并将其单独保留为'$query'。现在可以了。 :)
  • 您必须导入 Builder 类 (use Illuminate\Database\Eloquent\Builder;)
  • 是的,确实是正确的答案和解释。 “请注意,您必须为两者选择关系列,否则 Laravel 不知道如何连接两者”这才是真正的答案
【解决方案2】:

我认为你的选择很糟糕。在 laravel 中使用查询生成器。

试试这个

$user=DB::table('users')->join('customer_details','user.id','=','customer_details.id')->select('email','phone','first_name','last_name')->where('id','=',Auth::user()->id)->first();

我想您在 customer_details 中也使用 id 作为主键。

【讨论】:

    【解决方案3】:

    你可以用这个

    $user = User::select('id', 'email', 'phone')
    ->where('id', Auth::user()->id)
    ->with('customer_details:id,user_id,name,foo,other_column,...') // you get the idea here
    ->first();
    

    【讨论】:

      【解决方案4】:

      在您的 User.php 文件中,您错过了指定 localKey 与外键进行比较:

      return $this-&gt;hasOne('App\Models\CustomerDetails', 'user_id');

      应该是:有3个参数:(Model, 'Compare key with', 'Local key')

      return $this-&gt;hasOne('App\Models\CustomerDetails', 'user_id','id');

      【讨论】:

        猜你喜欢
        • 2017-02-22
        • 2021-12-24
        • 2019-06-15
        • 2013-04-03
        • 1970-01-01
        • 2021-05-19
        • 1970-01-01
        • 2016-11-05
        • 1970-01-01
        相关资源
        最近更新 更多