代码之家  ›  专栏  ›  技术社区  ›  Ber Tsacianegu del Tepuy

如何在模型中添加新字段并雄辩地使用它

  •  1
  • Ber Tsacianegu del Tepuy  · 技术社区  · 6 年前

    我正在尝试以下方法:我有一个名为Pub的模型,它有以下字段:“id”、“name”、“address”、“longitude”、“latitude”、“schedule”、“photo”等。

    因为我需要知道Pub和用户之间的距离,所以我创建了一个函数,该函数使用经度和纬度计算Pub模型中的距离:

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

    我在这里使用这个函数(也在Pub模型中):

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

    然后,我的问题是如何将该字段添加到Pub模型中,并使用该字段按距离排序我的Pub。

    我能做的第一件事是附加:

    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
    

    }

    我怎么能在这里使用accesors和mutators,或者类似的东西?。。。

    非常感谢!!

    4 回复  |  直到 6 年前
        1
  •  1
  •   Chirag Patel    6 年前

    好的,您可以在函数中添加一个字段 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');
    }
    
        2
  •  0
  •   AddWeb Solution Pvt Ltd    6 年前

    您应该尝试以下操作:

    请在模型中的表字段中添加以下代码:

    /**
         * Attributes that should be mass-assignable.
         *
         * @var array
         */
        protected $fillable = ['yorr_field1','yorr_field1','yorr_field3'];
    
        3
  •  0
  •   apokryfos    6 年前

    我认为您无法在查询中执行此操作,但在集合中执行此操作应该很容易:

    $pubs = Pub::all()->sortBy(function ($pub) {
         return $pub->pubDistance();
    });
    
        4
  •  0
  •   user5283119 user5283119    6 年前

    在getPubs函数中定义它,因为 $pubs 是一个集合,我们可以使用sortBy/sortByDesc方法按升序或降序对集合进行排序。在这种情况下,我们希望升序首先有最低的数字。

    资料来源: Laravel Documentation / sortBy

    第二来源: Similar to this SO answer

    public function getPubs()
    {
        $pubs = Pub::all();
        $sorted = $pubs->sortBy('pub_distance_to_user');
        return $sorted;
    }