指定された地域内にあり、特定の緯度と経度に近い場所のリストを返すコードを書いています。データベースのレイアウトは、ビジネスを含むロケーションテーブル、リージョンを定義するRegionテーブル(リージョンを識別するスラッグであるUrlName)、リージョンをLocationsにマップするregionLocationテーブルがあることです。SQLクエリから計算されたフィールドをYii2 ActiveRecordモデルに追加する
SQLクエリはかなり毛深いですが、返されるモデルでアクセス可能にしたい "Distance"という名前の仮想列を計算します。ここで
は私の場所のモデルに表示されたコードの短縮版である: public static function getByRegionAndLatLong($regionName, $lat, $long) {
$sql = "SELECT
`Location`.`LocationId`,
`Location`.`Latitude`,
`Location`.`Longitude`,
(
3959 * acos (
cos (radians(:Latitude))
* cos(radians(latitude))
* cos(radians(longitude) - radians(:Longitude))
+ sin (radians(:Latitude))
* sin(radians(latitude))
)
) AS Distance
FROM Location
LEFT JOIN RegionLocation RL
ON RL.LocationId = Location.LocationId
LEFT JOIN Region R
ON R.RegionId = RL.RegionId
WHERE R.UrlName= :UrlName
ORDER BY Distance ;
";
return Location::findBySql($sql, [
':Latitude' => $lat,
':Longitude' => $long,
':UrlName' => $UrlName
])->all();
}
問題は、私は、クエリを実行すると、私はその計算された「距離」の列の中に含まれたいということです結果。しかし、 "Distance"という名前のデータベースには実際のフィールドが存在しないため、Yii2のActiveRecordクラスはフィールドを生成されたモデルに追加しません。
"Distance"という名前のLocationテーブルに列を作成することで回避できますが、データベースを変更せずにこれを行う方法があることを期待しています。
私の最終的な目的は、モデルにLocationオブジェクトの配列を返し、各Locationオブジェクトに "Distance"属性があるようにすることでした。その後、コントローラは次のようなコードを使用してJSONフィードを生成します:
public function actionGetStudiosByLatLong($regionName = '', $latitude='', $longitude='') {
\Yii::$app->response->format = 'json';
return Location::getByRegionAndLatLong($regionName, $latitude, $longitude);
}
機能はモデルにありますか?行のコレクションを返しますか? – scaisEdge
修正。しかし、それは最終的にセット全体をjsonオブジェクトとして出力するWebサービスのためのものです。 – TMorgan