【问题标题】:Laravel Global scope for specific Routes and it's sub routesLaravel 特定路由的全局范围及其子路由
【发布时间】:2016-11-16 22:49:37
【问题描述】:

假设有一个像这样的Test 模型:

class Test extends Model
{
        public $primaryKey = 'test_id';
        public function questions ()
        {
            return $this->belongsToMany('App\Question', 'question_test', 'test_id', 'question_id')->withPivot('weight');
        }
}

还有一个像这样的Question 模型:

class Question extends Model
{
        public $primaryKey = 'question_id';
        public function tests ()
        {
            return $this->belongsToMany('App\Test', 'question_test', 'question_id', 'test_id')->withPivot('weight');
        }
}

问题模型字段如下:

question_id
text
correct
active  => can be true or false
created_at
updated_at

如您所见,这两个模型之间存在ManyToMany 关系。

我的应用中有两个单独的部分,一个用于管理员用户,另一个用于公共用户。

管理员可以对问题和测试执行任何操作。比如在测试中添加一些问题、删除、编辑等。

但另一方面,公共用户只能测试和相关的活跃问题(意味着他们的活跃领域是真实的)。

假设一些管理员路由如下:

http://myapp.dev/Admin/tests
http://myapp.dev/Admin/test/5/questions
http://myapp.dev/Admin/test/5/question/create
http://myapp.dev/Admin/test/5/remove

一些用户路线是:

http://myapp.dev/Dashboard
http://myapp.dev/tests-list
http://myapp.dev/test/5/questions

为此,我知道我可以在Question 模型中像这样使用query-scopes

public function scopeActive($query)
{
    return $query->where('active', 1);
}

当我只想获取活动问题时,必须这样做:

$test->questions->active()->get();

但我对用户面板上的问题执行了许多操作,因此如果想对选择问题使用active() 方法,这既困难又耗时。

我不能使用全局范围,因为这会影响在整个项目中运行的所有问题查询。

有没有一种方法可以为公共用户可以看到的某些特定路由和子路由定义全局(或本地)范围?

或者有其他方法可以解决这个问题?

更新:

除了提到的那些,用户还可以有一些角色。例如,管理员用户可以从管理面板切换到用户面板。在这种情况下,当他在用户面板上时,我只想显示活动问题。

【问题讨论】:

    标签: php laravel


    【解决方案1】:

    您可以通过将路由包装在 中间件 中来做到这一点。通过运行 php artisan make:middleware HideInactiveQuestions

    创建 HideInactiveQuestions.php
    <?php
    
    namespace App\Http\Middleware;
    
    use App\Question;
    use Closure;
    use Illuminate\Database\Eloquent\Builder;
    use Illuminate\Support\Facades\Auth;
    
    class HideInactiveQuestions
    {
        /**
         * Handle an incoming request.
         *
         * @param  \Illuminate\Http\Request  $request
         * @param  \Closure  $next
         * @return mixed
         */
        public function handle($request, Closure $next, $guard = null)
        {
            Question::addGlobalScope('active', function(Builder $builder) {
                $builder->where('active', '=', 1);
            });
    
            return $next($request);
        }
    }
    

    接下来,在Kernel.php注册你的中间件

    protected $routeMiddleware = [
        ....
        'restrict.public' => \App\Http\Middleware\HideInactiveQuestions::class,
    ];
    

    现在,已被此中间件 (restrict.public) 包装的路由将被您的范围过滤。

    【讨论】:

      猜你喜欢
      • 2015-10-31
      • 1970-01-01
      • 2013-08-07
      • 2016-04-10
      • 2018-03-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-19
      相关资源
      最近更新 更多