【问题标题】:How to access an Eloquent relationship using an associative array key如何使用关联数组键访问 Eloquent 关系
【发布时间】:2015-02-04 20:01:52
【问题描述】:

假设我的列表模型与属性模型具有一对多关系:

class Listing extends Eloquent {
    public function attrs() {
        return $this->hasMany('Attribute');
    }
}

class Attribute extends Eloquent {
    public function listing() {
        return $this->belongsTo('Listing');
    }
}

属性有一个代码和一个值。在处理清单时,我希望能够使用属性的代码获取特定属性,如下所示:

$val = Listing::find($id)->attrs[$code]->value;

上面这行显然行不通。有很多方法可以解决这个问题(例如,维护一个由代码索引的内部关联属性数组并将其填充到 attrs() 方法中;提供一个 getter 函数并通过 attrs 数组进行暴力搜索),但我想知道是否有一种优雅的方式可以使用 Laravel 内置的东西来做到这一点。

有比我上面建议的更好的想法吗?

【问题讨论】:

    标签: laravel eloquent relationship


    【解决方案1】:

    您可以在 Laravel 集合上使用带有闭包的 first() 方法:

    $val = Listing::find($id)->attrs->first(function($model) use ($code){
       return $model->code == $code;
    })->value;
    

    但请注意,如果没有模型匹配,first() 将返回 null,并且您会收到异常(因为您无法访问非对象的 ->value)

    为避免将其包装在 if 中:

    $attribute = Listing::find($id)->attrs->first(function($model) use ($code){
       return $model->code == $code;
    });
    $val = $attribute ? $attribute->value : 'default';
    

    或者你可以过滤关系,我认为这更优雅:

    $attribute = Listing::find($id)->attrs()->where('code', $code)->first();
    $val = $attribute ? $attribute->value : 'default';
    

    【讨论】:

    • 好的,是否有类似的解决方案可以急切加载 attrs 关系?我应该在我原来的问题中提到这一点......
    • 如果它们是急切加载的,请使用 first() 和过滤闭包
    • 对。不过,如果我没记错的话,这基本上相当于我在模型上使用自定义 getter 并通过 attrs 数组进行蛮力搜索的第二个解决方案。但是您确实回答了以 Laravel 方式执行此操作的问题,谢谢。
    • 是的。好吧,我不会说蛮力。它只是循环遍历数组,直到代码匹配。我不会认为这太糟糕了......
    猜你喜欢
    • 2019-10-25
    • 1970-01-01
    • 1970-01-01
    • 2015-11-22
    • 1970-01-01
    • 2011-12-24
    • 2016-08-13
    • 1970-01-01
    • 2013-01-24
    相关资源
    最近更新 更多