【问题标题】:getting model belongsTo attributes获取模型 belongsTo 属性
【发布时间】:2014-03-30 10:30:26
【问题描述】:
class Batch extends Eloquent {
    public function coupons() {
        return $this->hasMany('Coupon');
    }
}

class Coupon extends Eloquent {
    public function batch() {
        return $this->belongsTo('Batch');
    }
    public function price() {
        $batch = $this->batch;
        return $batch->price;
    }
}

$coupon->price 给了我这个错误:-

LogicException 关系方法必须返回一个对象类型 照亮\数据库\雄辩\关系\关系

但是,$coupon->batch->price 工作正常。

我错过了什么?

【问题讨论】:

    标签: laravel laravel-4


    【解决方案1】:

    花点时间了解一下您在这里实际拥有的物品。

    当您调用$this->batch; 时,您不再链接关系查询 - 您实际上已经从数据库中检索到信息。为了定义该查询,您必须使用以下几种方法之一:

    Coupon::with('batch.price')->get();
    

    你当然可以用关系来做,但是已经晚了,我不确定 Price 在这个方案中的确切位置,因为我没有看到与批处理相关联的方法。大概你可以这样做:

    public function price()
    {
        return $this->batch->price;
    }
    

    如果价格是批次的衍生产品。

    【讨论】:

    • 奇怪的是,$this->batch->price 也不起作用。我确实尝试过这个选项。我认为@alexrusel 已经成功了
    【解决方案2】:

    您的问题是您定义了一个非关系方法price(),但您将其称为关系方法(即您将其称为属性而不是方法)。

    您应该用来获取Coupon 价格的代码是:

    $coupon->price();
    

    关系事情起作用的原因(即$coupon->batch 超过$coupon->batch())是Laravel 有一些特殊的逻辑——基本上它会捕捉到你试图访问一个属性(在这种情况下是->batch)并检查是否有相应的方法(->batch())。如果有,它会调用它并期望它返回一个关系,然后根据它是单结果关系还是多结果关系,调用该关系上的 ->first()->get()

    所以你的代码中发生的事情是你调用了$coupon->price,而 Laravel 在幕后决定,因为有一个 ->price() 方法,所以它必须是一个关系。它调用该方法,检查它是否返回 Laravel 关系类型之一,如果没有,则抛出 LogicException

    一般的经验法则是这样的:

    • 如果您想要实际属性(即在表上定义的任何内容)或关系查询的结果,请使用属性访问
    • 如果您想要其他任何内容(即使用方法定义的行为),您必须直接调用该方法

    此外,有时将关系称为方法而不是属性是有充分理由的 - 调用方法会返回您可以添加查询构建器约束的内容,而调用属性会得到所有结果。所以说Coupons 可以启用或禁用(例如),以下成立:

    • $batch->coupons 获取该批次所有的优惠券
    • $batch->coupons()->whereEnabled(1)->get() 为您提供给定批次的所有已启用优惠券
    • $batch->coupons()->orderBy('order')->get() 为您获取该批次拥有的所有优惠券,按名为 order 的字段排序
    • $coupon->batch 为您获取给定优惠券的批次

    希望这能解释 Eloquent 使用方法与关系属性之间的区别,以及为什么所有增强的行为(例如您的示例中的优惠券价格,但不是批量价格,这是固有行为)必须作为方法调用。

    【讨论】:

    • 感谢 laravel 魔法的精彩解释。我以为幕后发生了类似的事情,但我无法完全确定
    • 是的,它没有真正记录在案。 Eloquent 关系文档中提到了集合与查询构建器,但没有提到它不能用于 other 事物。无论如何,很高兴能帮上忙。
    • 我认为你有一个错字:->first() ->get()
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-04
    • 2017-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多