在 Laravel Eloquent 中使用“with()”函数连接列

Posted

技术标签:

【中文标题】在 Laravel Eloquent 中使用“with()”函数连接列【英文标题】:Concat columns using “with()” function in Laravel Eloquent 【发布时间】:2015-06-13 22:11:07 【问题描述】:

我正在尝试将不同表中的两列concat合并为一列。

$user = User::with(array('Person'=>function($query)
    $query->selectRaw('CONCAT(prefix_person.name, " - ", prefix_user.code) as name, prefix_user.id');
))->lists('name', 'id');

在我的person class我有这个方法:

public function User()

    return $this->hasOne('User');

在我的user class 我有这个:

public function Person()

    return $this->belongsTo('Person', 'person_id');


我收到以下错误:

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'name' in 'field list' (SQL: select `name`, `id` from `prefix_user`)

当我尝试时

$user = User::with(array('Person'=>function($query)
    $query->selectRaw('CONCAT(prefix_person.name, " - ", prefix_user.code) as name, prefix_user.id')->lists('name', 'id');
));

我收到了这个错误:


我已经使用了几次selectRaw,但从来不需要将它加入 with (join)。

【问题讨论】:

你不能使用acessor 来代替它吗?这将使您的逻辑更易于理解和扩展。 @Ravan Acessors 很好,但我不知道这些如何与lists 一起工作并加入。你能举个例子吗? 哦,我现在看到问题了,让我考虑一下。 【参考方案1】:

问题在于 Eloquent 将首先查询 users 表,然后才查询 people 表,因此一个查询不知道另一个查询,因此连接不起作用。

您可以通过Query Builder 使用join 来执行此操作。会是这样的:

$user = DB::table('users as u')
    ->join('persons as p', 'p.id', '=', 'u.person_id')
    ->selectRaw('CONCAT(p.name, " - ", u.code) as concatname, u.id')
    ->lists('concatname', 'u.id');

编辑: 而且,正如@michel-ayres 评论所建议的那样,只要您有该领域的访问者:

public function getFullNameAttribute()  
    return $this->attributes['name'] . ' - ' . $this->attributes['code'];

您可以使用自己的模型来执行连接和列表:

User::join('person','person.id','=','user.person_id')
    ->select('person.name', 'user.code', 'user.id')
    ->get()
    ->lists('full_name', 'id');

【讨论】:

Eeyup,你找到了我问题的根源:/我关注了你的first suggestion,并在我的班级中创建了一个访问者,遵循this example at laravel's forum。我仍然认为有点难看(如果这项工作像 linq 那样工作,那么它会调用 2x 查询),但至少使用 Eloquent。这是决赛: User::join('person','person.id','=','user.person_id')->orderBy('person.name', 'ASC')->select ('person.name', 'user.code', 'user.id')->get()->lists('full_name', 'id');在模型中我有一个方法public function getFullNameAttribute() return $this->attributes['name'] . ' - ' . $this->attributes['code']; 如果可能,请在您的答案中添加(不要更改)评论=)谢谢 @MichelAyres 我猜你可以完全摆脱->get()。你能测试一下它是否正确,以便我更新答案吗? 我在没有->get() 的情况下进行了测试,但收到错误消息,提示我没有full_name。我认为它需要它来填充function getFullNameAttribute,所以我可以在lists 上使用它。【参考方案2】:

你可以通过简单的查询来解决它,

User::join('persons as p', 'p.id', '=', 'users.person_id')
       ->get([
            'id',
            DB::raw('CONCAT(p.name,"-",users.code) as name')
        ])
       ->lists('name', 'id');

或者,换一种方式

User::join('persons as p', 'p.id', '=', 'users.person_id')
      ->select(
          'id',
          DB::raw('CONCAT(p.name,"-",users.code) as name')

        )
       ->lists('name', 'id');

【讨论】:

以上是关于在 Laravel Eloquent 中使用“with()”函数连接列的主要内容,如果未能解决你的问题,请参考以下文章

在 Eloquent 查询/Laravel 5.2 中使用变量

Laravel:在 API 测试中使用 Eloquent 模型

如何在 Laravel 5.8 中使用 Eloquent 进行查询?

在 Laravel 中使用 Eloquent 进行更高级的数据库查询

如何使用 Eloquent 在 Laravel 中开始查询?

如何在 laravel 5 中使用 Eloquent 更新数据透视表