在Laravel 4中,我使用Eager Loading来实现ManyToMany关系:
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
查询生成器有一个名为“列表”的方法,应该可以解决这个问题。但是在Eager Load ???的情况下它不起作用
public function categories()
{
return $this->belongsToMany('Category')->lists('category_id');
}
答案 0 :(得分:4)
它不起作用的原因是因为当急切加载它时,使用with
方法,Laravel期望一个关系方法返回一个Illuminate\Database\Eloquent\Relations\Relation
对象,以便它可以调用{{1 }} 在上面。当您调用get
时,查询已经运行,而返回的内容则是数组。
为减少数据传输,您可以执行的操作是在查询上使用lists
方法,然后在类别集合上运行select
。例如:
<强> Model.php 强>
lists
<强> Whatever.php 强>
function categories() {
return $this->belongsToMany('Category')->select('id');
}
答案 1 :(得分:1)
将以下代码添加到Model / BaseModel:
/**
* 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');
答案 2 :(得分: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];