在我的用户模型上,我有以下内容:
public function isOnline()
{
return $this->hasMany('App\Accounting', 'userid')->select('rtype')->latest('ts');
}
会计表有活动记录,我希望在使用时返回用户ID的字段'rtype'的最新值。
在我的控制器中,我正在执行以下操作:
$builder = App\User::query()
->select(...fields I want...)
->with('isOnline')
->ofType($realm);
return $datatables->eloquent($builder)
->addColumn('info', function ($user) {
return $user->isOnline;
}
})
但是我没有为表中的用户获取'rtype'的值,也没有错误。
答案 0 :(得分:1)
看起来你没有正确定义你的关系。您的isOnline
方法会创建HasMany
关系,但会运行select
方法,然后运行latest
方法,最终会返回Builder
个对象。< / p>
正确的方法是只返回方法中的HasMany
对象,它将被视为关系。
public function accounts()
{
return $this->hasMany('App\Accounting', 'userid');
}
然后,如果您想在isOnline
课程中使用App\User
辅助方法,可以添加以下内容:
public function isOnline()
{
// This gives you a collection of \App\Accounting objects
$usersAccounts = $this->accounts;
// Do something with the user's accounts, e.g. grab the last "account"
$lastAccount = $usersAccounts->last();
if ($lastAccount) {
// If we found an account, return the rtype column
return $lastAccount->rtype;
}
// Return something else
return false;
}
然后在您的控制器中,您可以急切加载关系:
$users = User::with('accounts')->get(['field_one', 'field_two]);
然后,您可以对每个App\User
对象执行任何操作,例如调用isOnline
方法。
修改强>
经过一些进一步的挖掘,你的关系似乎是导致问题的select
。我在自己的一个项目中做了类似的事情,发现我的关系没有返回任何结果。虽然添加latest
似乎没有问题。
因此,您应该至少在关系定义中删除select
部分。当您只想在急切加载关系时检索某些字段时,您应该能够在使用with
时指定它们:
// Should bring back Accounting instances ONLY with rtype field present
User::with('accounts:rtype');
至少Laravel 5.5是这种情况,我不确定以前的版本。有关详情,请参阅标有预先加载特定列
的标题下的here答案 1 :(得分:0)
感谢Jonathon
public function accounting()
{
return $this->hasMany('App\Accounting', 'userid', 'userid');
}
public function isOnline()
{
$rtype = $this->accounting()
->latest('ts')
->limit(1)
->pluck('rtype')
->first();
if ($rtype == 'Alive') {
return true;
}
return false;
}
$builder = App\User::with('accounting:rtype')->ofType($filterRealm);
return $datatables->eloquent($builder)
->addColumn('info', function (App\User $user) {
/*
THIS HAS BEEN SUCCINCTLY TRIMMED TO BE AS RELEVANT AS POSSIBLE.
ARRAY IS USED AS OTHER VALUES ARE ADDED, JUST NOT SHOWN HERE
*/
$info[];
if ($user->isOnline()) {
$info[] = 'Online';
} else {
$info[] = 'Offline';
}
return implode(' ', $info);
})->make();