【问题标题】:Laravel scope in Model with Relation not working模型中的 Laravel 范围与关系不起作用
【发布时间】:2015-03-11 06:10:40
【问题描述】:

我有一个名为 owners 的表,它是商店所有者的列表,我想查询该表及其关系 stores 并获取商店与用户的距离。现在用户位置是硬编码的,但如果我能让它工作,我计划将它传递给查询范围。任何提示都非常感谢,谢谢!

<?php class Owner extends Eloquent {

protected $table = 'owners';    

public function scopeDistance($query) {

    $lat = '45.529999';
    $lng = '-122.680000';

    return $query->select(DB::raw("*,
                          ( 3959 * acos( cos( radians(?) ) *
                            cos( radians( lat ) )
                            * cos( radians( lng ) - radians(?)
                            ) + sin( radians(?) ) *
                            sin( radians( lat ) ) )
                          ) AS distance"))
            ->setBindings([$lat, $lng, $lat]);

}

public function stores()
{
    return $this->belongsTo('Store','store_id')->Distance();
}

public function storesDist()
{
    $lat = '47';
    $lng = '-124';
    return $this->belongsTo('Store','store_id')->select(DB::raw("*,
                          ( 3959 * acos( cos( radians(?) ) *
                            cos( radians( lat ) )
                            * cos( radians( lng ) - radians(?)
                             ) + sin( radians(?) ) *
                             sin( radians( lat ) ) )
                           ) AS distance"))
             ->setBindings([$lat, $lng, $lat]);
}

<?php

class OwnersController extends \BaseController {


public function getStoresNearUserA()
{

 // This returns  Call to undefined method Illuminate\Database\Query\Builder::Distance()
 return Owner::orderBy('id')->with('stores')->get();

 }

public function getStoresNearUserB()
{

 // This works
 return Owner::orderBy('id')->with('storesDist')->get();

}

****************************************************已更新

RE: First solution

// app/models/BaseModel.php
<?php

class BaseModel extends Eloquent {


public function scopeDistance($query) {

    return $query->orderBy('id');

}


....app/models/Store.Php
<?php 


class Store extends \Eloquent {

    protected $table = 'owners';


....app/models/Owner.Php
<?php 


class Owner extends \BaseModel {

    protected $table = 'owners';

    public function stores()
    {
        return $this->belongsTo('Store','store_id')->Distance();
    }


...app/controllers/OwnerController.php  
<?php

class OwnersController extends \BaseController {



public function getStoreOwners()
{

        return Owner::orderBy('id')->with('stores')->get();
  }

...My Error :
Call to undefined method Illuminate\Database\Query\Builder::Distance()

【问题讨论】:

    标签: laravel eloquent query-builder


    【解决方案1】:

    setBindings 中有错误 - where 是默认值。因此,只需将第二个参数设置为 select 就可以了:

    public function scopeDistance($query, $lat, $lng) 
    {    
        return $query->select(DB::raw("*,
                              ( 3959 * acos( cos( radians(?) ) *
                                cos( radians( lat ) )
                                * cos( radians( lng ) - radians(?)
                                ) + sin( radians(?) ) *
                                sin( radians( lat ) ) )
                              ) AS distance"))
                ->setBindings([$lat, $lng, $lat], 'select');
    }
    

    你也可以使用

    ->addBinging($lat, 'select')->addBinding($lng, 'select')->addBinding($lat, 'select');
    

    这将是安全的,因为现在,如果 select 有任何其他绑定(我承认非常罕见,但仍然......)你会搞砸查询。

    另外请注意,您不能像这样在关系查询中使用 Owner 模型范围。我建议你在BaseModel 中定义这个范围,然后OwnerStore 模型将扩展它,你将能够在两者中使用范围。

    【讨论】:

    • 看起来不错,非常感谢!我会在今晚晚些时候回家时确认。
    猜你喜欢
    • 2019-03-25
    • 2016-05-01
    • 2021-05-14
    • 1970-01-01
    • 2015-12-02
    • 2012-07-06
    • 2018-01-10
    • 2014-01-09
    • 2018-09-13
    相关资源
    最近更新 更多