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

7
我正在尝试将来自不同表的两列连接成一列。
$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类中,我有这个方法:
public function User()
{
    return $this->hasOne('User');
}

在我的用户类中,我有这样一个:

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

我遇到了这个错误:

error


我之前使用过selectRaw几次,但从未在联接中使用过。


你不能使用一个访问器来连接它吗?这样做会使你的逻辑更容易理解和扩展。 - Ravan Scafi
@Ravan 访问器很好,但我不知道它们如何与listsjoins一起使用。你能提供一些例子吗? - Michel Ayres
哦,我现在明白问题了,让我想一会儿。 - Ravan Scafi
3个回答

12
问题在于Eloquent会先查询users表,之后才是persons表,所以一个查询不知道另一个查询的情况,因此连接不起来。
你可以使用查询构建器,使用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');

哎呦,你找到了我的问题的根源 :/ 我按照你的第一个建议在我的类中创建了一个访问器,遵循了laravel论坛上的这个例子。我仍然认为它有点丑(如果像Linq一样工作,那么它会调用两次查询),但至少使用了Eloquent。这是最终结果: - Michel Ayres
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']; } - Michel Ayres
1
如果可能的话,请在您的答案中添加(不要更改)注释=)谢谢 - Michel Ayres
@MichelAyres 我猜你完全可以摆脱 ->get()。你能测试一下看看是否正确,这样我就可以更新答案了吗? - Ravan Scafi
我在没有使用 ->get() 的情况下进行了测试,结果出现了错误,提示我没有 full_name。我认为它需要填充 function getFullNameAttribute,以便我可以在 lists 上使用它。 - Michel Ayres
哦,我明白了。它正在使用 Collection 中的 lists() - Ravan Scafi

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

0

您可以使用以下示例查询来解决此问题

->when($request->value != null, fn ($q) => $q->where(DB::raw("CONCAT(col1,'',col2)"), '=', '' . $request->value. ''))


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接