Mysql Laravel Eloquent-如何在范围查询中作为模型列或集合属性返回计算值
我正在尝试获取一个靠近经过身份验证的用户的用户列表,并使用Laravel的Eloquent返回他们之间的距离。我使用原始SQL使其正常工作,但现在我几乎做到了使用最有说服力的SQL使其正常工作 因此,在用户模型上,我有以下方法:Mysql Laravel Eloquent-如何在范围查询中作为模型列或集合属性返回计算值,mysql,laravel,eloquent,model,coordinates,Mysql,Laravel,Eloquent,Model,Coordinates,我正在尝试获取一个靠近经过身份验证的用户的用户列表,并使用Laravel的Eloquent返回他们之间的距离。我使用原始SQL使其正常工作,但现在我几乎做到了使用最有说服力的SQL使其正常工作 因此,在用户模型上,我有以下方法: public function getUsersAround($coordinates, $radius = 5) { return $this->whereHas('location', function ($query) use ($coordinat
public function getUsersAround($coordinates, $radius = 5)
{
return $this->whereHas('location', function ($query) use ($coordinates, $radius) {
$query->distance($coordinates, $radius);
})->paginate(10);
}
然后在位置模型上,我有以下范围:
public function scopeDistance($query, $coordinates, $radius)
{
return $query
->join('profiles', 'profiles.id', '=', 'locations.profile_id')
->having('distance', '<', $radius)
->selectRaw("profile_id,
(6371 * ACOS(COS(RADIANS($coordinates->latitude))
* COS(RADIANS(latitude))
* COS(RADIANS(longitude) - RADIANS($coordinates->coordinates))
+ SIN(RADIANS($coordinates->latitude))
* SIN(RADIANS(latitude)))) AS distance")
->orderBy('distance', 'asc');
}
公共函数范围距离($query,$coordinates,$radius)
{
返回$query
->联接('profiles','profiles.id','=','locations.profile\u id'))
->拥有('distance','distance($coordinates,$radius));
我看到所有用户+每个用户对象上的新距离属性(具有正确的值),但是如果我只是返回查询并dd(auth()->user()->getUsersAround($coordinates,$radius))
在控制器内,距离属性就不再存在了
在返回用户列表时,是否有方法在范围查询中返回计算出的距离,并将其保留在Users对象上
谢谢!这是因为您在一个范围内使用的是不正确的get()。本地范围用于定义常见的约束集(如用于过滤数据)。 有关更多详细信息,请查看上的文档
要向选择结果添加内容,可以使用。如果要在结果中包含距离,需要使用
距离属性加载位置
关系。由于您已经在位置模型的查询范围中选择了距离
,因此可以非常轻松地实现这一点:
公共函数getUsersRound($coordinates,$radius=5)
{
返回$this->whereHas('location',function($query)use($coordinates,$radius){
$query->distance($coordinates,$radius);
})->与([
“位置”=>函数($query)使用($coordinates,$radius){
$query->select('locations.*')->距离($coordinates,$radius);
}
])->分页(10);
}
注意带('location')的,它急切地加载位置模型。我添加了一个select('locations.*')
,这样location
关系将有自己的属性,距离($coordinates,$radius)
也将选择profile\u id
和distance
属性
因此,当您在控制器内调用auth()->user()->getUsersAround($coordinates,$radius)
时,您可以使用$user->location->distance
访问距离属性:
$users=auth()->user()->getUsersAround($coordinates,$radius);
foreach($users作为$user){
$distance=$user->location->distance;
}
get()是正确的,我忘了将其从示例中删除。当我使用dd($query->distance($coordinates,$radius))时,我将其放在那里只是为了查看结果
但是,基于我已经编写的代码,我找不到使用addSelect的方法。你能给我一个例子说明我如何使用它吗?@DanielR。只需遵循Laravel的官方文档。不幸的是,你的解决方案不起作用,因为我无法获得本地范围内的距离并将其添加到addSelect()中正如您所建议的,但感谢您的尝试。您的解决方案很有效!但是,我不得不对其进行一些调整,因为with()
方法需要关联数组来约束急切的加载。感谢您的帮助!感谢您的编辑,确实需要关联数组语法!