2015-01-13 5 views
1

У меня есть таблица под названием owners, которая является списком владельцев магазинов, и я хотел бы запросить эту таблицу с ее отношением stores и получить расстояние от магазина от пользователя. Пока пользовательское местоположение жестко закодировано, но я планирую передать это в область запроса, если я могу заставить его работать. Любые советы очень ценятся, спасибо!Laravel scope в Model with Relation не работает

<?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() 

ответ

1

у вас есть ошибка в setBindings - where по умолчанию. Так просто использовать 2-й набор пар для 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, затем модели Owner и Store расширят ее, и вы сможете использовать область действия в обоих.

+0

Выглядит хорошо, спасибо вам большое! Я подтвержу позже вечером, когда вернусь домой. –

Смежные вопросы