rap-2-h
rap-2-h

Reputation: 32028

Add custom attribute in eloquent model

Here is a raw SQL query:

SELECT name, area, point(area) AS center FROM places;

I want to get an Eloquent model based on this query. Here is the Model:

class Place extends Model
{
    protected $visible = ['name', 'area'];
}

So, I want to get the center property if I run this code:

return response()->json( Place::all() );

center is missing. I don't know how to add the center property in my Place object. I don't want to build a raw query in my controller, is there any solution with mutator or something like this? (The only thing I want to call is Place::all(), I really want to use Eloquent Model in controllers, not an SQL query).

Upvotes: 2

Views: 6694

Answers (2)

Amelia
Amelia

Reputation: 2970

Use a combination of Mutators and the $appends property. Here's an example:

<?php namespace App;

use Illuminate\Database\Eloquent\Model;

class Place extends Model {

    protected $appends = ['center'];

    public function getCenterAttribute()
    {
        return $this->point($this->getRawAttribute("area"));
    }

    protected function point($area)
    {
        // logic for SQL POINT(), etc
    }
}

The $appends property will mean that the mutated attribute is included in JSON/array output when $model->toJson() or $model->toArray() is called (which Response::json() does)

The reason for doing point logic in code is because with eloquent models, you'd hit the N+1 query problem when fetching a list of places and their centers, and that's not a great idea for your database.

Your query wouldn't be used when fetching data for the model from the database, either, since the default query for models is

select * from `table` where id = :id

Which is then figured out internally to set up data on the model.

Upvotes: 6

Maksym
Maksym

Reputation: 3428

You may want to take a look at this: http://laravel.com/docs/5.0/eloquent#global-scopes. It should help you build the query that will always get center along with the rest of data.

Upvotes: 0

Related Questions