2014-02-16 61 views
4

下面是一个示例数据库表(users):雄辩模型的默认范围?

id - int(11) auto_increment 
name - varchar(100) 
banned - int(1) 

banned是一个布尔值,它是0false)由缺省值。如果用户被禁止,则值为1

我想排除禁止所有查询的用户默认。我可以创建一个query scope然后在任何地方使用。但是,我更喜欢简单地在默认情况下进行检查。

我也可以创建自己的newQuery - 方法,像这样:

// Inside User-model, which extends Eloquent 
public function newQuery($excludeDeleted = true) 
{ 
    $builder = parent::newQuery($exludeDeleted); 
    $builder->where('banned', '=', '0'); 
    return $builder; 
} 

但是,这样一来我就无法关闭这种行为。我可能想在我的私人管理面板中看到被禁用的用户,但无法执行,因为此限制将应用于通过Eloquent完成的任何查询。

有关如何解决此问题的任何想法?

+0

据我所知,覆盖'newQuery()'确实是唯一的方法。我发现自己处于类似的情况,我考虑创建一个scopeBase(),这是一个个人约定(不是Laravel的!),并努力记住调用'Model :: base() - > get )'等,只要我需要访问模型。这很不理想,但是可以省略'newQuery()'。我想他们俩都很糟糕。 JohnTaa的答案似乎可以帮助你。 – alexrussell

+1

做了一些挖掘。你可以应用全局范围[像这样](https://github.com/laravel/framework/issues/3897#issuecomment-41351443)。我给出的例子是可重用的作用域;你可能不需要,因为只有用户可以被禁止。 – mpen

回答

0

你为什么不使用配置变量为:

public function newQuery($excludeDeleted = true) 
{ 
    $builder = parent::newQuery($exludeDeleted); 
    if (Config::get('hide_banned_users', true) !== false) { 
     $builder->where('banned', '=', '0'); 
    } 
    return $builder; 
} 

和更改配置值时,你需要看到禁止用户。

1

这听起来很像soft deleting,但与banned_at而不是deleted_at。如果默认行为不是为了显示被禁用户,我认为当你需要他们时(管理面板),明确要求禁止的用户更为直观(如withTrashed)。

+0

我的功能与软删除类似,是的。 –

+0

@MarttiLaine我也在调查。还没有找到解决方案,但[本](https://github.com/laravel/framework/blob/1181e63a49921612cf441cbad65b345ccabdcb75/src/Illuminate/Database/Eloquent/SoftDeletingTrait。php#L104-L112)可能会给我们一些线索。 – mpen

4

我强烈建议使用存储库设计模式进行数据库查询,而不要在控制器和其他地方进行直接的查询。

// Quick example, not tested 
class UserRepositoy { // You should create an interface and maybe super class for handling common cases like caching, find(), all() etc 

    protected $include_banned = false; 
    protected $model; 

    public function __construct() // you can use DI here 
    { 
      $this->model = new User; 
    } 

    public function setIncludeBanned($bool) 
    { 
     $this->include_banned = $bool; 
    } 

    protected function includeBanned($query) 
    { 
     if ($this->include_banned) { 
      return $query->where('banned', 1); 
     } 
    } 

    public function find($id) 
    { 
     $res = $this->model->where('id', $id); 

     $res = $this->includeBanned($res); 

     return $res->get(); 
    } 

} 

现在你可以instiate在任何你需要查询资料库类,你有统一的API调用。在Laravel,很容易在这里和那里传播小的雄辩查询,但从长远来看,更新/更改和应付真的很烦人。试试谷歌搜索Laravel Design Pattern,并有大量的信息和例子。已经让我的一天已经几次了。

如果有必要,这种模式也可以使整个雄辩与其他事物更容易沟通。