【问题标题】:Select specific fields from array of Eloquent collecton | Laravel从 Eloquent 集合中选择特定字段 |拉拉维尔
【发布时间】:2018-12-05 09:23:43
【问题描述】:

我有一个包含模型对象数组的集合对象,我想从模型中选择特定字段。

Illuminate\Database\Eloquent\Collection Object
(
    [items:protected] => Array
        (
            [0] => App\Model Object
            [1] => App\Model Object
            [2] => App\Model Object
        )
)

现在我想从模型对象中选择一些字段。当我尝试执行以下语法时

print_r($collection->select('filed a', 'field b'));

然后出现以下错误。

Macroable.php 第 74 行中的 BadMethodCallException:方法选择确实如此 不存在。

我认为 select 可以直接与 eloquent 模型一起使用,但不能与集合一起使用。

【问题讨论】:

    标签: php laravel


    【解决方案1】:

    你在找only()

    $filtered = $collection->only(['list', 'of', 'fields', 'to', 'keep']);
    

    或者mapWithKeys()

    【讨论】:

    • 我想的只是或者pluck,但是搜索到的值不是数组键,而是对象属性。
    • @Thomas 我想pluck() 也适用于对象。我用一组模型对象进行了测试,结果很好。
    • @Thomas 现在我明白你的意思了,每个对象的键都没有保留。更好的方法是映射它。
    • @AlexMalikov 实际上only() 与集合的第一级键一起使用。
    【解决方案2】:

    select is not present on the Collection class 是正确的。

    你可以做的是map, filter or transform the collection你自己,例如

    $whiteList = ['filed a', 'field b'];
    
    $filledOnly = $collection->map(function ($item) use ($whiteList) {
        $properties = get_object_vars($item);
    
        foreach ($properties as $property) {
            if(!in_array($property, $whiteList) {
                  unset($item->{property});
            }
        }
    
        return $item;
    });
    

    问题出在 PHP 中,一旦在对象上设置了属性(或字段),您确实必须取消设置它或创建同一类的新对象)。这就是我想出这个解决方案的原因。

    问题是:您最初是如何检索此集合的,您能否不将选择添加到查询本身?

    【讨论】:

    • 我也想要和我一样的结构。所以你的回答会返回给我数组,而不是雄辩的模型。
    • @sachinkumar 您应该在问题中指定您想要什么。在那里你什么也没说你需要相同的模型,只是你想从模型中选择字段。
    【解决方案3】:

    最好的办法是在对模型执行查询之前选择您需要的字段。但是,如果要保留初始集合,可以使用 map(),如果要覆盖集合(例如),则可以使用 transform()

    $selected_fields = ['filed a', 'field b']
    $models->map(function ($zn) use ($selected_fields) { 
            return $zn->newInstance(array_only($zn->getAttributes(), $selected_fields));
        })->toArray();
    

    newInstance() 方法创建该模型的新空实例,然后getAttributes() 检索模型中存在的属性。所以在这个过程中保留了初始模型。

    作为参考,newInstance() 的实现可以在Illuminate\Database\Eloquent\Model 类中找到,如下(在 Laravel 5.2 上):

        /**
         * Create a new instance of the given model.
         *
         * @param  array  $attributes
         * @param  bool  $exists
         * @return static
         */
        public function newInstance($attributes = [], $exists = false)
        {
            // This method just provides a convenient way for us to generate fresh model
            // instances of this current model. It is particularly useful during the
            // hydration of new objects via the Eloquent query builder instances.
            $model = new static((array) $attributes);
    
            $model->exists = $exists;
    
            return $model;
        }
    

    【讨论】:

      猜你喜欢
      • 2019-04-24
      • 2018-05-10
      • 2016-08-07
      • 2018-09-05
      • 2015-05-07
      • 2014-11-12
      • 2019-06-17
      • 1970-01-01
      • 2019-06-29
      相关资源
      最近更新 更多