# How To Add A New Field To A Model And Use It In Eloquent

## 17 May 2018 - 1 answer

I'm trying the following: I have a model, called Pub, that has the following fields: "id","name","address","longitude","latitude","schedule","photo", etc.

As I need to know the distance between Pub and User, so I've created a function that calculates the distance in Pub Model using longitude and latitude:

``````public function pubDistance()
{
\$userLat = '';
\$userLong = '';

\$pubLat = \$this->latitude;
\$pubLong = \$this->longitude;

if(!(\$userLat && \$userLong))
{
\$userLat = 40.4169473;
\$userLong = -3.7035285;
}

\$latDelta = \$latTo - \$latFrom;
\$lonDelta = \$lonTo - \$lonFrom;

\$a = pow(cos(\$latTo) * sin(\$lonDelta), 2) +
pow(cos(\$latFrom) * sin(\$latTo) - sin(\$latFrom) * cos(\$latTo) * cos(\$lonDelta), 2);

\$b = sin(\$latFrom) * sin(\$latTo) + cos(\$latFrom) * cos(\$latTo) * cos(\$lonDelta);

\$angle = atan2(sqrt(\$a), \$b);

\$distance = round(\$angle * \$earthRadius, 2);

return \$distance;

}
``````

And I use this function here (inside Pub model too):

``````public function getPubDistanceToUserAttribute()
{
return \$this->pubDistance();
}
``````

Then the problem I have is how to add the field to Pub model and use to order my pubs by distance.

The first thing I could do it appending:

``````protected \$appends = ['pub_distance_to_user'];
``````

But I'm having problems in my controller to order by that new field:

``````public function getPubs()
{
\$pubs = Pub::all();

return \$pubs;
}
``````

This is what I have:

``````{
"id": 1,
"name": "Dr. Nikko Braun",
"longitude": "118.9395890",
"latitude": "-62.3235600",
"schedule": "1986-11-13 10:15:48",
"photo":
"email": "[email protected]",
"phone": "1-841-349-8925 x684",
"pub_distance_to_user": 15556.09
``````

}

How I could use accesors and mutators here, or something like this in this case?...

Thanks a lot!!

Ok so you can add a field in the function `getPubs()` by using the foreach loop,

Try this,

``````public function getPubs()
{
\$pubs = Pub::all();

foreach(\$pubs as \$pub){
\$pub->pub_distance_to_user = Pub::pubDistance();
}

return \$pubs->sortBy('pub_distance_to_user');
}
``````

EDIT:

I think you can define your function to calcluate distance with arguments, like this way

``````public function pubDistance(\$pubLat,\$pubLong)
{

\$userLat = '';
\$userLong = '';

if(!(\$userLat && \$userLong))
{
\$userLat = 40.4169473;
\$userLong = -3.7035285;
}

\$latDelta = \$latTo - \$latFrom;
\$lonDelta = \$lonTo - \$lonFrom;

\$a = pow(cos(\$latTo) * sin(\$lonDelta), 2) +
pow(cos(\$latFrom) * sin(\$latTo) - sin(\$latFrom) * cos(\$latTo) * cos(\$lonDelta), 2);

\$b = sin(\$latFrom) * sin(\$latTo) + cos(\$latFrom) * cos(\$latTo) * cos(\$lonDelta);

\$angle = atan2(sqrt(\$a), \$b);

\$distance = round(\$angle * \$earthRadius, 2);

return \$distance;

}
``````

And then you have to call function by `Pub::pubDistance(\$pub->latitude,\$pub->longitude);`

``````public function getPubs()
{
\$pubs = Pub::all();

foreach(\$pubs as \$pub){
\$pub->pub_distance_to_user = Pub::pubDistance(\$pub->latitude,\$pub->longitude);
}

return \$pubs->sortBy('pub_distance_to_user');
}
``````