我正在构建一个应用程序,其中一个帐户可以拥有许多服务,所有信息都与服务相关。例如:
帐户A有3个服务,每个服务都有页面。
为了避免有人在保存页面时修改service_id,目前我正在这样做:
if(Yii::$app->request->isPost) {
$post = Yii::$app->request->post();
$model->load($post);
$model->service_id = $this->service->id;
}
在哪里$ model-> service_id = $ this-> service-> id可以帮助我在将表加载到模型后分配选定的service_id,并避免有人从表单发送service_id。
但是如果将来有人开发“文档”,我希望避免开发人员在所有查询中处理此service_id。
所以首先我想我可以尝试:
public function beforeFind($queryData) {
parent::beforeFind();
$queryData['conditions'] = array('service_id' => 2);
return $queryData;
}
但是仍然需要开发人员来实现它。因此,也许有一种方法可以创建一个“ BaseService”模型,其中所有其他与服务相关的模型都应从该模型扩展而又不确定如何:
也许有一个简单的解决方案,由于不确定的长时间工作,我使自己过于复杂了。
答案 0 :(得分:3)
这是适用于所有查询的默认条件。如果您的应用程序是基于ActiveRecord类(不执行直接SQL查询或即时QueryBuilder)之上构建的,则可以简单地覆盖find()
方法在您的Model类中:
public static function find()
{
/* you can add more dynamic logic here */
return parent::find()->where(['service_id' => 2]);
}
默认情况下,Yii2中的所有控制器都使用Model::find()
从数据库中检索数据,添加这样的条件应该足以不检索任何service_id
不同于2的东西。通过ID直接HTTP GET请求如果不满足该条件,则应输出404,并将其作为不同模型类中的关系数据进行检索应返回经过过滤的数组。
重要提示:要不破坏该实现,您需要:
始终使用 ActiveRecord。否则,您需要手动将条件添加到查询中。
(不正确) 要小心何时使用 asArray(),因为它忽略了ActiveRecord功能(请参阅{{ 3}})。否则,您需要手动重新声明条件,例如: Account::find()->where(['service_id' => 2])->asArray()->all();
始终使用 andWhere()合并条件,因为 where()将覆盖/忽略默认值。示例:Account::find()->andWhere('age>30')->all();
答案 1 :(得分:0)
要重新使用此类过滤器,您可以将其放入custom ActiveQuery。
在您的ActiveRecord中:
public static function find() {
return (new ActiveQuery(get_called_class()));
}
ActiveQuery:
public function service($service = 2) {
return $this->andWhere(['service_id' => $service]);
}
基于ActiveRecord的模型:
public static function find() {
return (new ActiveQuery(get_called_class()))->service(2);
}
或者
$model->find()->service(1);
另外,this可能很有趣(为每个方案设置默认值)