1

在 Laravel 4 中,我将 Eager Loading 用于多对多关系:

public function categories()
{

    return $this->belongsToMany('Category');

}

它返回如下类别:

    "categories": [
        {
            "id": 1,
            "priority": 1,
            "title": "My category 1",
            "created_at": "2013-08-10 18:45:08",
            "updated_at": "2013-08-10 18:45:08"
        },
        {
            "id": 2,
            "priority": 2,
            "title": "My category 2",
            "created_at": "2013-08-10 18:45:08",
            "updated_at": "2013-08-10 18:45:08"
        }
    ],

但我需要的是:

    "categories": [1,2] // References category id's only

查询生成器有一个称为“列表”的方法,它应该可以解决问题。但是在急切负载的情况下它不起作用???

public function categories()
{

    return $this->belongsToMany('Category')->lists('category_id');

}
4

3 回答 3

4

它不起作用的原因是因为当急切加载它时,使用该with方法,Laravel 期望一个关系方法返回一个Illuminate\Database\Eloquent\Relations\Relation对象,以便它可以调用get它。当您调用lists时,查询已经运行并且返回的是一个数组。

为了减少数据传输,您可以做的是select在查询上使用该方法,然后lists在类别集合上运行 a。例子:

模型.php

function categories() {
    return $this->belongsToMany('Category')->select('id');
}

随便.php

$posts = Post::with('Category')->get();
$categories = $posts->categories;

// List only the ids
$categoriesIds = $categories->lists('id');
于 2013-08-11T04:26:51.427 回答
1

将以下代码添加到您的模型/基础模型中:

/**
 * Set additional attributes as hidden on the current Model
 *
 * @return instanceof Model
 */
public function addHidden($attribute)
{
    $hidden = $this->getHidden();

    array_push($hidden, $attribute);

    $this->setHidden($hidden);

    // Make method chainable
    return $this;
}

/**
 * Convert appended collections into a list of attributes
 *
 * @param  object       $data       Model OR Collection
 * @param  string|array $levels     Levels to iterate over
 * @param  string       $attribute  The attribute we want to get listified
 * @param  boolean      $hideOrigin Hide the original relationship data from the result set
 * @return Model
 */
public function listAttributes($data, $levels, $attribute = 'id', $hideOrigin = true)
{

    // Set some defaults on first call of this function (because this function is recursive)
    if (! is_array($levels))
        $levels = explode('.', $levels);

    if ($data instanceof Illuminate\Database\Eloquent\Collection) // Collection of Model objects
    {
        // We are dealing with an array here, so iterate over its contents and use recursion to look deeper:
        foreach ($data as $row)
        {
            $this->listAttributes($row, $levels, $attribute, $hideOrigin);
        }
    }
    else
    {
        // Fetch the name of the current level we are looking at
        $curLevel = array_shift($levels);

        if (is_object($data->{$curLevel}))
        {
            if (! empty($levels))
            {
                // We are traversing the right section, but are not at the level of the list yet... Let's use recursion to look deeper:
                $this->listAttributes($data->{$curLevel}, $levels, $attribute, $hideOrigin);
            }
            else
            {
                // Hide the appended collection itself from the result set, if the user didn't request it
                if ($hideOrigin)
                    $data->addHidden($curLevel);

                // Convert Collection to Eloquent lists()
                if (is_array($attribute)) // Use specific attributes as key and value
                    $data->{$curLevel . '_' . $attribute[0]} = $data->{$curLevel}->lists($attribute[0], $attribute[1]);
                else // Use specific attribute as value (= numeric keys)
                    $data->{$curLevel . '_' . $attribute} = $data->{$curLevel}->lists($attribute);
            }
        }
    }

    return $data;
}

您可以像这样在模型/集合对象上使用它:

// Fetch posts data
$data = Post::with('tags')->get(); // or use ->first()

// Convert relationship data to list of id's
$data->listAttributes($data, 'tags');

$data 现在将包含以下对象存储:

{
    "posts": [
        {
            "title": "Laravel is awesome",
            "body": "Lorem Ipsum...",
            "tags_id": [ 1, 2, 3 ]
        },
        {
            "title": "Did I mention how awesome Laravel is?",
            "body": "Lorem Ipsum...",
            "tags_id": [ 1, 2, 4 ]
        }
    ]
}

它还支持嵌套关系:

// Fetch posts data
$data = Post::with('comments', 'comments.tags')->get(); // or use ->first()

// Convert relationship data to list of id's
$data->listAttributes($data, 'comments.tags');
于 2013-12-03T11:02:26.797 回答
0

如果所有建模请求都是这种情况category,您可以设置visible array

喜欢protected $visible = array('category_id');

现在每个对类别模型的请求将category_id只检索

在你的情况下 -

Class Category extends Eloquent{

    protected $visible=array('category_id');
    ...
}

注意-它将category_id作为对象返回的集合,但是如果您需要一个数组,则必须使用toArray()查询构建器的方法来获取一个数组category_id

为了得到你所需要的,你可以试试这个

$cat_id=Category::all()->toArray();
$arrid=array();
array_walk_recursive($cat_id,function($value,$key) use (&$arrid){
  array_push($arrid,$value);
})
//$arrid will contain only category_id's like
//$arrid=[1,2,3];
于 2013-08-11T07:43:02.377 回答