0

On my User model I have the following:

public function isOnline()
{
    return $this->hasMany('App\Accounting', 'userid')->select('rtype')->latest('ts');
}

The accounting table has activity records and I'd like this to return the latest value for field 'rtype' for a userid when used.

In my controller I am doing the following:

    $builder = App\User::query()
        ->select(...fields I want...)
        ->with('isOnline')
        ->ofType($realm); 

    return $datatables->eloquent($builder)
        ->addColumn('info', function ($user) {
            return $user->isOnline;
        }
    })

However I don't get the value of 'rtype' for the users in the table and no errors.

4

2 回答 2

1

看起来您没有正确定义您的关系。您的isOnline方法创建了一个HasMany关系,但运行该select方法,然后在latest其上运行该方法,最终将返回一个Builder对象。

正确的方法是仅从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 就是这种情况,我不确定以前的版本。有关更多信息,请参阅此处,在标有Eager Loading Specific Columns的标题下

于 2018-01-29T22:11:15.817 回答
0

谢谢乔纳森

用户模型

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();
于 2018-01-30T17:32:19.993 回答