从Eloquent关系中选择特定列

时间:2015-09-22 21:14:04

标签: laravel laravel-5

我的应用程序中有以下模型:

user.php的

var queue = {};

var fixedUpdate = setInterval(function() { //do all the requests in queue 

    $.each(queue, function(key, val) { //for each request present in the queue

        //do something (requests are about updating display or some global variables)

        /*...*/

        //after completing the request we delete it from the queue
        delete queue[key];
    });

}, 1);

CustomerDetails.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');
    }

}

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

<?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');
    }
}

现在我想要它只是从我的用户表中选择电子邮件电话号码,然后选择 first_name <来自 customer_details 表的/ strong>, last_name ,但每当我尝试此操作时,它总是将 customer_details 作为 null 返回。这个函数将在一个页面上单独使用,这意味着有其他页面可能需要所有细节而不是这个,所以我想创建一个单独的Eloquent关系来执行此操作。

4 个答案:

答案 0 :(得分:4)

您需要在选择中包含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不知道如何连接两者

答案 1 :(得分:0)

我认为你的选择很糟糕。在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作为主键。

答案 2 :(得分:0)

您可以使用此

$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();

答案 3 :(得分:0)

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

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

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

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