Php Laravel:从关系查询的第一个()结果中获取列值

Php Laravel:从关系查询的第一个()结果中获取列值,php,laravel,laravel-5.1,relationships,Php,Laravel,Laravel 5.1,Relationships,我试图从模型的belongTomany关系查询的第一个结果中获取一个单列值,因为我返回的是关系的->first()结果,我希望$code->reward->title可以工作,但它不能工作 我得到一个关系方法,该方法必须返回类型为illumb\Database\Eloquent\Relations\Relationserror的对象 我试图做的是获取链接到特定代码的当前奖励的标题-code\u奖励pivot表有一个valid\u from和expires\u在日期,因为链接到代码的奖励会随着时间

我试图从模型的belongTomany关系查询的第一个结果中获取一个单列值,因为我返回的是关系的
->first()
结果,我希望
$code->reward->title
可以工作,但它不能工作

我得到一个
关系方法,该方法必须返回类型为illumb\Database\Eloquent\Relations\Relations
error的对象

我试图做的是获取链接到特定代码的当前奖励的标题-
code\u奖励
pivot表有一个
valid\u from
expires\u在
日期,因为链接到代码的奖励会随着时间的推移而变化,因此需要获取该代码的当前活动奖励

这是我的密码:

型号:代码

public function rewards()
{
    return $this->belongsToMany('App\Reward')->withPivot('valid_from', 'expires_at')->withTimestamps();
}



public function reward()
{
    $now = Carbon::now();
    return $this->rewards()
        ->wherePivot('valid_from', '<', $now)
        ->wherePivot('expires_at', '>', $now)
        ->first();
}
查看:代码/索引

@foreach ($codes as $code)

    {{$code->id}}
    {{$code->reward->title}}

@endforeach
非常感谢您的帮助

更新

public function rewards()
{
    return $this->belongsToMany('App\Reward')->withPivot('valid_from', 'expires_at')->withTimestamps();
}



public function reward()
{
    $now = Carbon::now();
    return $this->rewards()
        ->wherePivot('valid_from', '<', $now)
        ->wherePivot('expires_at', '>', $now)
        ->first();
}
不幸的是,下面的两个建议(
$code->reward()->title
getRewardAttribute()
都返回了一个
试图获取非对象属性的错误

如果我从code->reward()方法中删除
->first()
,并在视图中将
$code->reward->title
替换为
$code->reward->first()
,它将整个奖励模型作为json进行响应,但是
$code->->->reward->->()->title
仍然返回试图获取非对象属性的
错误

更新2 如果我在视图中执行
{{dd($code->raward->title)}
,我将获得奖励标题,但是如果我只执行
{{{$code->raward->title}
,我不会

$code->reward->title
@Show
视图中工作正常,因此可能是控制器的
@index
方法提供的代码集合没有传递必要的数据或没有以必要的格式传递数据

已解决 该问题是由索引视图中的
foreach
循环中的
$code->reward
中的一个返回
null
!第一个没有返回,因此
dd()
工作,但循环一碰到
null
就崩溃了。
一旦我擦除并刷新了数据库(并确保我的种子只添加有效数据!),它就工作了。执行
{{$code->raward?$code->raward->title:'}}}
修复了这个问题。Grrr。

尝试在代码模型中设置这个方法,因为查询生成器将有效的\u from和过期的\u at视为字符串,而不是日期

public function getDates()
    {
        return ['valid_from','expired_at'];
    }

您的语句失败,因为
$code->reward->title
告诉Laravel您已经在名为
reward()
的方法中定义了代码模型上的关系。但是,您的关系实际上是在方法
rewards()
中定义的。相反,
reward()
是您制作的模型上的自定义方法。将其作为方法而不是关系调用是获得所需内容的最快方法

{{$code->reward()->title}}
正如@andrewtweber在下面指出的,您还可以将自定义的
reward()
方法设置为属性访问器。为此,只需将函数重命名为
getRewardAttribute()
,然后您就可以像最初那样在视图中调用它

或者,您可以完全摆脱
reward()
方法,并将所有逻辑移到控制器中,这样可能更有意义。您必须使用受限的急切加载来实现这一点。因此,在控制器中,您将有如下内容:

$codes = App\Code::with(['rewards' => function ($query) {
    $query->wherePivot('valid_from', '<', $now)
          ->wherePivot('expires_at', '>', $now);
])->get();
{{$code->rewards->first()->title}}

但是,使用我的第一个解决方案会更简单,所以这完全取决于您。

或者将
reward()重命名为
getRewardAttribute()
他可以使用它作为
$code->奖励->标题
大家好,谢谢你们的帮助,不幸的是前两个选项都不起作用,我已经更新了问题,知道为什么会这样吗?你能发布你的控制器方法调用你的代码模型并将数据传递给视图吗?@AndyNoelker我已经在问题中添加了这一点另外,还有一个关于将
->first()
移动到视图的额外注意事项,这可能会有所帮助??嗯,这很奇怪。但是,您的更新为我带来了一些标志。假设您将方法名称保留为
renward()
。任何时候你想用这个方法做任何事情,你都需要包含括号。因此,当你删除
->first()
并进行调用时,它应该是
$code->raward()->first()->title
。同样,如果你想引用实际的关系,你不需要括号:
$code->rewards
。如果这仍然没有帮助,你可以尝试不使用碳日期吗?也许这是一个疯狂的格式问题。@AndyNoelker在
$code->rewards()->first()方面运气不好->title
还将方法更改为
公共函数return(){return$this->returns()->wherePivot('expires_at','=',null);}
并且也没有运气:-(是的,我很困惑为什么
dd($code->return->title)
之所以有效,是因为在没有括号的情况下调用它意味着它是一个应该返回一个关系的关系,但实际上它是一个应该返回一组模型的方法。你能发布你的
dd
的结果吗?我想知道它返回的是什么。如果它不是一个有说服力的对象,那么该语法就不起作用了。also,你有一些没有奖励的代码吗?试着用
@excler($code->reward->isEmpty())
@endexcler
来包装你的语句。我们必须弄清楚这是刀片问题还是逻辑问题。