php – 在Laravel模型上的Trait中查询查询
一点背景……
我的应用程序中有两个模型是“可定位的”.我可以非常轻松地在存储库中编写查询以返回我需要的内容,但是,我确信在Laravel Scopes和Traits等的帮助下可以做得更好(我可能错了). 所以,我提出了以下解决方案: 示例摘要模型 abstract class AbstractModel extends Model implements SomeOtherStuff? { public function scopeNearby(Builder $query)? { return $query->selectRaw(' ( 6373000 * acos( cos( radians( ' . $this->location->latitude . ' ) )? * cos( radians( X(' . $this->location->table . '.location) ) )? * cos( radians( Y(' . $this->location->table . '.location) ) - radians( ' . $this->location->longitude . ' ) )? + sin( radians( ' . $this->location->latitude . ' ) ) * sin( radians( X(' . $this->location->table . '.location) ) ) ) ) AS distance ') // I wanted to use ->with('location') below instead of ->join() but it didn’t work ->join($this->location->table,$this->location->primaryKey,'=',$this->primaryKey); } // All other Abstract stuff here } 示例用户模型 class User extends AbstractModel implements SomeOtherStuff {? /** * Get the location of the user.? */ public function location() {? return $this->hasOne(‘AppModelsUserLocation','user_id');? } // All other model stuff here } 示例用户控制器 class UserController extends AbstractController? { /** * Return the nearby users. * * @return IlluminateHttpJsonResponse */? public function nearby() { $users = $this->shield->user()->nearby()->toSql(); // Print out the query to ensure it is structured correctly echo $users;? } } 我的问题 上面的解决方案是有效的,这是非常错误的(在我看来)!附近()范围仅适用于“可定位”的模型.当然,我认为最好的解决方案是实现这样的Trait: trait Locatable { /**? * Scope a query to include the distance from the current model.? * * @param IlluminateDatabaseEloquentBuilder $query * @return IlluminateDatabaseEloquentBuilder? */? public function scopeNearby(Builder $query)? { // Same as above implementation? }? } 这个问题是我需要的模型的属性受到保护,因此无法通过Trait访问… 我的问题 假设上述内容有意义,请参阅下面的问题: >有没有更好的方法来实现这个所需的功能,如果是这样,请有人指出我正确的方向? 解决方法
这就是它应该如何实际完成的
trait Locatable { /** * Scope a query to include the distance from the current model. * * @param IlluminateDatabaseEloquentBuilder $query * @return IlluminateDatabaseEloquentBuilder */ public function scopeNearby($query) { if(!$this->location) { return $query; } return $query->whereHas('location',function($query) { $query->selectRaw(' //Your query for distance (Use the getTable() function wherever required...) ) AS distance ') ->having('distance','<',25); } ); } } 回答你的问题. >以上是更好的方法.您应该使用whereHas()进行关系查询. (在控制器中的任何地方写下这个…仅用于测试目的) dd($user->with('locations')->toSql()); 如果您遇到任何问题,请告诉我…… (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |