Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Duplicate column names; resulting in error when casting the Location to Point (getting the binary data) #26

Open
Jacotheron opened this issue Feb 22, 2024 · 0 comments

Comments

@Jacotheron
Copy link

I was getting an error when casting the location column from the database to the Point, using the LocationCast in the array of model casts.

In short the error occurs on line 32 of the LocationCast.php file

In debugging the issue, and looking at my queries, I noticed that the location column, appears twice in the returned results, once with the ST_AsText version, but the first one returned is the raw binary data.

Looking through the package I noticed in the HasSpatial.php Trait overwrites the newQuery method from the Model, in order to add the select which converts the location binary data into usable data. Unfortunately, when it add this to the select, it also selects everything (which also includes the columns containing raw data). And there we get the issue.

After a bunch of fiddling, I have made a slightly improved newQuery method, that I am using on my models. Unfortunately this requires an extra array to be defined in your model (I called it "$all_attributes") - as we need the list (which should include all the attributes you might want to have retrieved, some of which may be from your hidden attributes).

    public function newQuery(): Builder
    {
        $wktOptions = config('laravel-spatial.with_wkt_options', true) === true
            ? ', \'axis-order=long-lat\''
            : '';

        $columns_to_skip = []; //holds a list of the columns we are overwriting with raw selects
        $selects = $this->all_attributes; // get a list of all the columns from the model we need to return
        $raw_selects = []; //stores the raw db select objects

        foreach ($this->getLocationCastedAttributes() as $column) {
            $raw_selects[] = DB::raw("CONCAT(ST_AsText(".$this->getTable().".".$column.$wktOptions."), ',', ST_SRID(".$this->getTable().".".$column.")) as ".$column);
            $columns_to_skip[] = $column;
        }

        $selects = array_diff($selects, $columns_to_skip); // strip out overwritten columns from the main selects

        return parent::newQuery()
            ->addSelect($selects)
            ->addSelect($raw_selects);
    }

The code starts as the package's standard way, but then we define a couple of arrays that will store details; then we get the location columns, and add these to the list to remove from the standard select list.

Unfortunately this code cannot be add to a trait (for using it with multiple models) in addition to the HasSpatial trait, as PHP does not allow traits defining the same method.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant