是否有可能在Eloquent中加载任意查询?

时间:2014-03-27 14:35:52

标签: laravel-4 eloquent eager-loading

我在Laravel 4工作,我有一个包含多个EducationProfiles的Child模型:

class Child extends EloquentVersioned 
{
public function educationProfiles()
    {
        return $this->hasMany('EducationProfile');
    }
}

如果我想为每个10岁以下的孩子获取所有的EducationProfiles,那就很容易了:

Child::where('date_of_birth','>','2004-03-27')->with('educationProfiles')->all();

但是说(就像我一样)我想用()来获取每个孩子的教育档案的计算值,例如:

SELECT `education_profiles`.`child_id`, GROUP_CONCAT(`education_profiles`.`district`) as `district_list`

理论上,()仅适用于人际关系,所以我是否有任何选项可以将district_list字段与我的子模型相关联?

编辑:实际上,我想知道是否('educationProfiles')生成的SQL相当于:

EducationProfile::whereIn('id',array(1,2,3,4))

或者它是否实际上等同于

DB::table('education_profiles')->whereIn('id',array(1,2,3,4))

我问的原因是前者我得到的是模型,如果是后者我会得到未建模的数据,因此我可能会把它弄得尽可能多。我假设with()会生成一个额外的集合模型。有人关心纠正或确认吗?

2 个答案:

答案 0 :(得分:1)

好吧,我想我已经破解了这个坚果。不,不可能急于加载任意查询。但是,Fluent查询构建器提供了这些工具,可以相对轻松地手动复制预先加载。

首先,我们利用原始查询:

$query = Child::where('date_of_birth','>','2004-03-27')->with('educationProfiles');
$children = $query->get();
$eagerIds = $query->lists('id');

接下来,使用$eagerIds过滤DB::table('education_profile')的方式与with('educationProfiles')过滤EducationProfile::...的方式相同

$query2 = DB::table('education_profile')->whereIn('child_id',$eagerIds)->select('child_id', 'GROUP_CONCAT(`education_profiles`.`district`) as `district_list`')->groupBy('child_id');
$educationProfiles = $query2->lists('district_list','child_id');

现在我们可以遍历$children,只需查找每个条目的$educationProfiles[$children->id]值。

好的,是的,这是一个明显的结构,但我还没有看到它在任何地方明确地列出,作为一种渴望加载任意计算的方法。

答案 1 :(得分:-1)

您可以在hasMany()调用中添加where子句,如下所示:

public function educationProfilesUnderTen() {
    $ten_years_ago = (new DateTime('10 years ago'))->format('Y-m-d');
    return $this->hasMany('EducationProfile')->where('date_of_birth', '>', $ten_years_ago)
}