使用Eloquent关系而不调用 - > get()

时间:2016-02-09 18:01:29

标签: php oop laravel eloquent

所以我有一个名为Pricetag的模型,它与Price有一个OneToMany关系。

我可以使用此功能从prices获取所有Pricetag

public function prices(){
    return $this->hasMany('App\Price');
}

并通过这样称呼:$pricetag->prices;

这一切都非常基础。当将函数用作->get()时,Eloquent会自动调用函数上的attribute函数。

现在我的问题:

如果我希望能够通过调用->price而不调用->first()来获取当前价格(作为价格对象,而不是价格集合)......我会这样做吗?

我现在有以下代码:

public function price($date = null){
    if($date === null){
        $date = Carbon::now();
    }
    return $this->prices()->orderBy('date', 'DESC')->where('date', '<=', $date);
}

当像$pricetag->price这样调用时,它会返回一组价格。

当像$pricetag->price()->first()这样调用时,它会将第一个价格作为price对象返回。

如何获取它,以便在调用它时像属性那样返回对象?或者是属性'syntax'结束的地方,我需要使用像->getPrice()

这样的方法

编辑找到一个干净的解决方案!

我制作了一个名为History的特征,如下所示:

namespace App\Traits;

use Carbon\Carbon;

    trait History {
        public $current_date = null;

        public function when($date){
            $this->current_date = $date;

            return $this;
        }

        public function getDateAttribute(){
            return $this->current_date === null ? Carbon::now() : $this->current_date;
        }
    }

这将允许我毫不费力地调用当前价格的$pricetag->price属性。如果我想得到明天或昨天的价格,或者我只是这样称呼它$pricetag->when($date)->price

需要过滤日期的Model内的功能只需拨打$this->date即可。

2 个答案:

答案 0 :(得分:2)

未测试代码,但请在Pricetag型号上试用:

 public function getPriceAttribute($value)
    {
        $date = Carbon::now();
        return $this->prices()->orderBy('date', 'DESC')->where('date', '<=', $date)->first();
    }

现在尝试拨打$pricetag->price。让我知道你得到了什么。

答案 1 :(得分:1)

使用具有关系方法/属性的参数是非常规的,但您应该能够获得您正在寻找的逻辑:

public function price($date = null) {
    if ($date === null) {
        $date = Carbon::now();
    }

    return $this->hasOne('App\Price')->orderBy('date', 'DESC')->where('date', '<=', $date);
}

通过将其定义为hasOne,该属性将返回对象,而不是Collection。当您访问该属性时,您将始终获得最新价格(因为您无法传递参数),但如果您使用关系方法,则可以传递您想要的日期约束:

// latest price
$price = $pricetag->price;

// other price
$otherPrice = $pricetag->price($someDate)->first();