【发布时间】:2014-11-11 11:25:44
【问题描述】:
我目前有三个模型,它们的 Eloquent 查询使用预加载。我的模型有这些关系:
class Template extends Eloquent {
public function user() {
return $this->belongsTo('User');
}
}
class User extends Eloquent implements UserInterface, RemindableInterface {
public function profiles() {
return $this->hasMany('Profile');
}
public function templates() {
return $this->hasMany('Template');
}
}
class Profile extends Eloquent {
public function user() {
return $this->belongsTo('User');
}
}
我的工作查询如下所示:
$templates = Template::with('user', 'user.profiles')
->where('public', '=', true)
->whereIn('type', $search_types)
->where('user_id', '!=', $user->id)
->paginate(8);
这似乎工作得很好,但我需要再添加一件事,这对我来说很难做到正确。我需要使用user 表中现有的lat 和long 列来更改此查询以考虑模板用户与当前用户的距离。我只希望查询返回其用户在当前用户 25 英里范围内的模板(理想情况下按距离排序,但该部分是可选的)。
我尝试向用户关系添加自定义计算列,如下所示:
$templates = Template::with(array('user' => function($query) use($user) {
$query->select('*')->selectRaw('(3959 * acos(cos(radians(?)) * cos(radians(lat)) * cos(radians(long) - radians(?)) + sin(radians(?)) * sin(radians(lat)))) AS distance', array($user->lat, $user->long, $user->lat));
}, 'user.profiles' => function($query) {
$query
}))
->where('public', '=', true)
->whereIn('type', $search_types)
->where('user_id', '!=', $user->id)
->having('distance', '<=', 25)
->orderBy('distance')
->paginate(8);
这不起作用,因为在预先加载时,初始查询中不存在distance 列,导致它在having 子句中失败。如果我将该部分移到匿名函数中并删除排序,它不会立即失败,但它只是忽略模板查询的距离,然后只抓取 25 英里内的相关用户,这似乎不是有帮助。
使用 Eloquent 获取我想要的数据的正确方法是什么?
【问题讨论】:
-
您的情况有什么解决方案吗?与我的相似,如果有一些想法来使用一些内置的 laravel 技术,那就太好了。