我从一个相当大的数据库中提取,出于安全考虑,我的数据库用户只能从学生表中选择有限数量的列:name,gradu_date和gender。但是在select *语句中返回了许多其他列。
在常规SQL中,如果我运行类似:
SELECT * FROM students
将在该表上返回错误。如果我运行雄辩的模型
,也是如此Students::all();
也会返回错误。
我知道在Eloquent中,您可以在定义类似于以下的关系时限制您的选择:
class Students extends Eloquent {
protected $table = 'student_info';
public function classes() {
return $this->hasMany('classes')->select(array('room', 'time'));
}
}
所以,我的问题是,可以在主模型上完成选择限制,类似于在类表上限制它。因此,当我运行Student::all();
时,它只选择我需要的列。
主要问题是每次我运行学生查询时,我每次都要做一个特定的选择命令,而不是只说“Student::all()
”。 Student :: find(1)也是如此;也会返回错误,因为它仍会运行SELECT * FROM student_info WHERE id = 1
。
我尝试设置$visible
变量,但仍然将sql等效为SELECT * FROM ...
任何人都有解决方案吗?
更新 请注意我在模型级别上寻找或解决方案,而不是控制器级别。我可以从控制器端进行选择,但这会破坏模型概念的目的,并且必须声明要在每个查询中选择的列。
谢谢! 特洛伊
答案 0 :(得分:4)
您可以创建一个中间类并重载all()
函数。我们称这个班为Elegant
<强> Elegant.php 强>
abstract class Elegant extends Model
{
public static $returnable = [];
public function all()
{
return $this->get(static::$returnable)->all();
}
}
然后扩展此类,并为其定义可返回列。
<强> Student.php 强>
<?php
class Student extends Elegant
{
public static $returnable = ['room', 'time'];
}
现在可以根据需要使用它:控制器中的Student::all()
。如果您将returnable
作为空数组,那么您将获得所有内容。
答案 1 :(得分:2)
您可以使用以下内容:
public function newQuery()
{
return parent::newQuery()->select('room', 'time');
}
将newQuery
方法放在Students
模型中,并使用正常使用的Student
模型。这是一种愚蠢的方式,但最容易。只需覆盖parent::query()
即可。通过这种方式,您将始终获得所选字段。
答案 2 :(得分:2)
扩展Jarek关于使用Global Scope的建议你可以这样做,我不是100%确定移除部分是正确的,但是需要测试。
<强> SelectLimitTrait.php 强>
trait SelectLimitTrait {
public static function bootSelectLimitTrait()
{
static::addGlobalScope(new SelectLimitScope);
}
public function getQueryable()
{
if(! $this->queryable ) return array('*');
return $this->queryable;
}
}
<强> SelectLimitScope.php 强>
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\ScopeInterface;
class SelectLimitScope implements ScopeInterface {
public function apply(Builder $builder)
{
$query = $builder->getQuery();
$queryable = $builder->getModel()->getQueryable();
$query->columns = $queryable;
}
public function remove(Builder $builder)
{
$query = $builder->getQuery();
$query->columns = null;
}
}
然后在你的Eloquent模型中说出这个:
<强> Students.php 强>
class Students extends \Eloquent {
use SelectLimitTrait;
protected $queryable = array('name','graduation_date', 'gender');
}
现在Students::all()
和Students::find(1)
等仅限于查询姓名,毕业日期和性别