Как добавить новое поле в модель и использовать его в Eloquent - PullRequest
0 голосов
/ 17 мая 2018

Я пытаюсь сделать следующее: у меня есть модель с именем Pub, которая имеет следующие поля: «id», «name», «address», «longitude», «latitude», «schedule», «photo"и т. д.

Поскольку мне нужно знать расстояние между пабом и пользователем, я создал функцию, которая вычисляет расстояние в модели паба по долготе и широте:

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

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

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

    $earthRadius = 6371;

    $latFrom = deg2rad($userLat);
    $lonFrom = deg2rad($userLong);
    $latTo = deg2rad($pubLat);
    $lonTo = deg2rad($pubLong);

    $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;

}

И здесь я использую эту функцию (также внутри модели паба):

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

Тогда у меня возникает проблема, как добавить поле в модель паба и использовать его для упорядочения пабов по расстоянию.

Первое, что я мог сделать, добавив:

protected $appends = ['pub_distance_to_user'];

Но у меня проблемы в контроллере, чтобы упорядочить по этому новому полю:

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

    return $pubs;
}

Вот что у меня есть:

{
"id": 1,
"name": "Dr. Nikko Braun",
"address": "453 Wyman Crossroad\nSouth Eliashaven, NY 75636",
"longitude": "118.9395890",
"latitude": "-62.3235600",
"schedule": "1986-11-13 10:15:48",
"photo": 
"email": "sylvester.rutherford@example.net",
"phone": "1-841-349-8925 x684",
"pub_distance_to_user": 15556.09

}

Как я могу использовать здесь аксессоры и мутаторы, или что-то подобное в этом случае? ...

Большое спасибо !!

Ответы [ 4 ]

0 голосов
/ 17 мая 2018

Определите это в вашей функции getPubs, так как $pubs - это коллекция, которую мы можем использовать метод sortBy / sortByDesc для сортировки коллекции по возрастанию или по убыванию. В этом случае мы хотим, чтобы по возрастанию сначала стояла самая низкая цифра.

Источник: Документация Laravel / sortBy

Второй источник: Аналогично этому SO-ответу

public function getPubs()
{
    $pubs = Pub::all();
    $sorted = $pubs->sortBy('pub_distance_to_user');
    return $sorted;
}
0 голосов
/ 17 мая 2018

Я не думаю, что вы можете сделать это в запросе, но это должно быть легко сделать в коллекции:

$pubs = Pub::all()->sortBy(function ($pub) {
     return $pub->pubDistance();
});
0 голосов
/ 17 мая 2018

Хорошо, поэтому вы можете добавить поле в функцию getPubs() с помощью цикла foreach,

Попробуйте это,

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

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

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

РЕДАКТИРОВАТЬ:

Я думаю, что вы можете определить свою функцию для расчета расстояние с аргументами, например, так:

public function pubDistance($pubLat,$pubLong)
{

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

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

$earthRadius = 6371;

$latFrom = deg2rad($userLat);
$lonFrom = deg2rad($userLong);
$latTo = deg2rad($pubLat);
$lonTo = deg2rad($pubLong);

$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;

}

А затем вам нужно вызвать функцию с помощью 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');
}
0 голосов
/ 17 мая 2018

Вы должны попробовать это:

Пожалуйста, добавьте ниже код с полем таблицы в вашей модели:

/**
     * Attributes that should be mass-assignable.
     *
     * @var array
     */
    protected $fillable = ['yorr_field1','yorr_field1','yorr_field3'];
...