我正在尝试查找{lat}/{long}
X半径范围内的所有邮政编码,但我收到的是TypeError
。
我收到此错误:
类型错误:传递给App \ Transformers \ PostcodesTransformer :: transform()的参数1必须是App \ Postcodes的实例,给出stdClass的实例,在/ home / vagrant / postcode-data / vendor / league / fractal中调用第338行的/src/Scope.php
查询是:
$postcodes = DB::select("Select
id,
postcode,
latitude,
longitude,
district,
postal_town,
county,
country,
northing,
easting,
type,
acos(sin(".$lat.")*sin(radians(latitude)) + cos(".$lat.")*cos(radians(latitude))*cos(radians(longitude)-".$lon.")) * ".$R." As distance
From (
Select *
From uk_postcodes
Where latitude Between ".$minLat." And ".$maxLat."
And longitude Between ".$minLon." And ".$maxLon."
) As FirstCut
Where acos(sin(".$lat.")*sin(radians(latitude)) + cos(".$lat.")*cos(radians(latitude))*cos(radians(longitude)-".$lon.")) * ".$R."< ".$rad."
Order by distance");
return $this->response->withCollection($postcodes, new PostcodesTransformer);
但DB::select
查询的结果会返回stdClass
。
我如何让它返回Postcodes
类的实例?
答案 0 :(得分:1)
这里有两个答案。第一个是我认为错误的方式,但它是对你的问题更直接的答案。
我们需要以某种方式使用Eloquent获取此查询,但为了处理该表,我们需要首先从postcodes表中进行选择,将查询转换为使用临时表。
DB::query("
Create Temporary Table FirstCut Select *
From uk_postcodes
Where latitude Between ".$minLat." And ".$maxLat."
And longitude Between ".$minLon." And ".$maxLon
);
现在我们可以使用您的模型将您的postcodes
表加入。我们必须从模型开始,因为这是返回App\Postcodes
Postcodes::join('FirstCut', 'FirstCut.zipcode', '=', 'postcodes.zipcode') // Guessing column names here
->selectRaw('id, postcode, latitude, longitude, district, postal_town, county, country, northing, easting, type,
acos(sin(".$lat.")*sin(radians(latitude)) + cos(".$lat.")*cos(radians(latitude))*cos(radians(longitude)-".$lon.")) * ".$R." As distance'
)
->whereRaw("acos(sin($lat)*sin(radians(latitude)) + cos($lat)*cos(radians(latitude))*cos(radians(longitude)-$lon)) * $R< $rad")
->orderByRaw('distance')
->get();
处理此问题的第二种方法是从PostcodeTransformers
中抽象逻辑,创建一个使用该逻辑的新逻辑,并且还可以处理stdClass
。然后,您需要做的就是传递新的StdClassTransformer
而不是PostcodesTransformer
。
答案 1 :(得分:0)
根据您的代码,您没有使用Laravel的Eloquent Model概念来对数据库进行查询。
所以你可以拥有像这样的Postcode对象集合:
创建一个名为Postcode
的模型,如下所示:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Postcode extends Model
{
protected $table = 'postcodes';
protected $guarded = ['id'];
}
然后在创建查询时,你可以这样做,你可以使用Laravel的查询构建器的方法 - selectRaw()
:
$postcodes = Postcode::selectRaw("
*,
acos(sin(".$lat.")*sin(radians(latitude)) + cos(".$lat.")*cos(radians(latitude))*cos(radians(longitude)-".$lon.")) * ".$R." As distance
From (
Select *
From uk_postcodes
Where latitude Between ".$minLat." And ".$maxLat."
And longitude Between ".$minLon." And ".$maxLon."
) As FirstCut
Where acos(sin(".$lat.")*sin(radians(latitude)) + cos(".$lat.")*cos(radians(latitude))*cos(radians(longitude)-".$lon.")) * ".$R."< ".$rad."
")
->orderBy('distance', 'asc')
->get();
现在,您将获得Postcode
模型对象的集合,而不是StdClass
。如果你更深入地打破你的选择原始查询会更好,因为在我看来它不会起作用!