Giter Site home page Giter Site logo

Comments (7)

Synchro avatar Synchro commented on August 20, 2024

I discovered I was calling create instead of update in my update controller method so I fixed that and now it does not give the mutator errors; it reports back immediately with partially updated values. So I'm doing this to convert the supplied lat & long into a point in the update method:

    $request->request->add(['location' => new Point($request->latitude, $request->longitude)]);
    $location->update($request->all());

This gives me this result in the response:

{
    "id": 1,
    "created_at": "2018-03-16 16:39:47",
    "updated_at": "2018-03-17 13:36:44",
    "type": "account",
    "name": "Smurf city",
    "address": "123 cup lane",
    "location": {
        "type": "Point",
        "coordinates": [
            150.15,
            21.21
        ]
    }
}

That looks like it has worked - but if I request that record again, it has not updated in the DB, even though timestamps are the same:

{
    "id": 1,
    "created_at": "2018-03-16 16:39:47",
    "updated_at": "2018-03-17 13:36:44",
    "type": "account",
    "name": "Smurf city",
    "address": "123 cup lane",
    "location": {
        "type": "Point",
        "coordinates": [
            -0.118092,
            51.509865
        ]
    }
}

I still don't see why the lat & long virtual properties are not visible and the location is.

from laravel-mysql-spatial.

Synchro avatar Synchro commented on August 20, 2024

I tracked down the query in the database log, and none of location, longitude, or latitude are included in the update query:

update `locations` set `updated_at` = '2018-03-17 13:36:44', `name` = 'Smurf city', `address` = '123 cup lane' where `id` = 1

from laravel-mysql-spatial.

Synchro avatar Synchro commented on August 20, 2024

Aha - I discovered that the location field is only updated if it's in fillable; being in spatialfields alone (what the docs suggest) isn't enough. But this means I can't implement this lat/long mapping transparently; the location property will always be visible, and it also doesn't explain why the fillable lat & long are ignored too.

from laravel-mysql-spatial.

Synchro avatar Synchro commented on August 20, 2024

Finally, I discovered a useful answer on Stackoverflow about virtual properties. Ultimately I needed to add these to my model to hide the location property, and to make longitude and latitude visible:

protected $hidden = [
    'location',
];

protected $appends = [
    'longitude',
    'latitude',
];

from laravel-mysql-spatial.

Synchro avatar Synchro commented on August 20, 2024

Just for completeness, I ran into another issue related to this. Because the location attribute is never submitted in an HTTP request, when you try to apply a mutator to it (like $this->location->setLng($longitude);), it will fail because location will not be in the model's attributes array. I had to add a dummy location value in the constructor for my model so it would exist later on when the mutator needs it:

public function __construct($attributes = [])
{
    $this->location = new Point(51.509865, -0.118092);
    parent::__construct($attributes);
}

The $attributes parameter is vital, and you must pass it through to the parent, because otherwise you're effectively unsetting all the submitted parameters, and you will probably get missing default value errors from your SQL layer later on (this was the cause of the missing values I noticed in an earlier comment in this thread).

This all seems incredibly convoluted and messy simply to provide a usable input format for a single Point value. Is this really how it's meant to work? Have I missed something vital?

from laravel-mysql-spatial.

Synchro avatar Synchro commented on August 20, 2024

Minor update: 22 months on and I've still not managed to make this work. I can't see any way of using point values if their data originates in a request. Does anyone have an example of using this package that doesn't involve internally generated points?

from laravel-mysql-spatial.

Synchro avatar Synchro commented on August 20, 2024

Setting a default value in the constructor really doesn't work, but I've found a better fudge for the null property problem. If the location is null at the time it's set, fill it with a default value:

public function setLatitudeAttribute(float $latitude): void
{
    if ($this->location === null) {
        $this->location = new Point(0, 0);
    }
    $this->location->setLat($latitude);
}

I'd still love to know how others deal with this.

from laravel-mysql-spatial.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.