如何在Laravel 4模型中为POINT数据列创建访问器?

5ssjco0h  于 2023-04-22  发布在  其他
关注(0)|答案(2)|浏览(83)

我有一个user_sessions表,其中有一个名为“geo_location”的列,它是一个POINT列,存储用户当前位置的纬度和经度值,如果不可用,则为NULL。
当我在Laravel中创建一个绑定到该表的Model时,它只有在geo_location字段完全隐藏时才有效。否则它会抛出JSON错误,因为它没有正确查询geo_location列中的单独X和Y值。
有没有一种方法可以让我在Laravel模型中创建一个访问器,它可以在数据显示之前操作数据,这样我就可以把它包含在我的结果中?
我是否需要修改我的UserSessions控制器并添加一个get()函数来使用原始SQL?

kqqjbcuj

kqqjbcuj1#

如果您使用的是PostgreSQL + PostGIS,这就是我在L4.1中所做的
位置的类型为几何(POINT),使用迁移表中的原始sql查询创建
表:

DB::statement("ALTER TABLE places ADD COLUMN location GEOMETRY(POINT, 4326)");

型号:

class Place extends Eloquent{
     //mass assignment of fillable field
     #fillable
     protected $fillable = array('name', 'attribute', 'location');
     // if you want to include your POINT data as a JSON attribute
     #append
     protected $append = array('location');
     // the DB:raw statement is particular to PostGreSQL + PostGIS, a native function of PostGIS
     // basically, find the id of the referred place
     // and run the PostGIS function that turns the geometry type to wkt text.
     #accessor
     public function getLocationAttribute(){
         $id =  $this->attributes['id'];
         $wkt = DB::table('places')->find( $id, array(DB::raw('ST_AsText(location) AS location')));
         $location = $wkt->location;
         return $location;
     }

 }

使用REST的示例输出如下所示:
{domain}/place/{1}

{
  id: 1,
  name: "Yellowstone",
  created_at: "2014-05-19 08:19:51",
  updated_at: "2014-05-19 08:19:51",
  location: "POINT(121.1 14.4)"
 }

注意事项:
使用默认访问器

$this->attributes['location']

返回一个十六进制对象,而不是一个字符串。所以我选择使用一个原始查询与PostGIS函数。

{
   id: 1,
   name: "Yellowstone",
   created_at: "2014-05-19 08:19:51",
   updated_at: "2014-05-19 08:19:51",
   location: "0101000020E61000006666666666465E40CDCCCCCCCCCC2C40"
 }

在WKT中,我希望你可以使用本地php脚本轻松地返回经度/纬度。:-)
我希望这能让您对如何创建访问器有所了解。

uyhoqukh

uyhoqukh2#

我在模型中使用了全局范围

use Illuminate\Database\Eloquent\Builder;
...
protected static function booted(): void
{
    static::addGlobalScope('geometry', function (Builder $query) {
        $query->select()->selectRaw("(ST_AsText(geo_location)) as geo_location");
    });
}

https://laravel.com/docs/10.x/eloquent#anonymous-global-scopes

相关问题