mae*_*mae 12 activerecord yii2 yii2-model yii2-validation
这似乎是一个微不足道的问题,但是我能想到的所有明显的解决方案都有其自身的缺陷.
我们想要的是能够仅为新记录设置任何默认的ActiveRecord属性值,使其在验证之前和验证期间可读,并且不会干扰用于搜索的派生类.
一旦我们实例化类,就需要设置和准备(new MyModel)->attr默认attr值,以便返回默认值.
以下是一些可能性和问题:
A)在MyModel超控的init()方法和分配默认值时isNewRecord,像这样是正确的:
public function init() {
if ($this->isNewRecord) {
$this->attr = 'defaultValue';
}
parent::init();
}
Run Code Online (Sandbox Code Playgroud)
问题:搜索.除非我们明确地取消设置我们的默认属性MySearchModel(非常容易出错,因为它太容易忘记),这也会在调用search()派生MySearchModel类之前设置值并干扰搜索(该attr属性已经设置,因此搜索将返回结果不正确).在Yii1.1中,这是通过在调用unsetAttributes()之前调用来解决的search(),但是在Yii2中不存在这样的方法.
B)在MyModel超控的beforeSave(),像这样的方法:
public function beforeSave($insert) {
if ($insert) {
$this->attr = 'defaultValue';
}
return parent::beforeSave();
}
Run Code Online (Sandbox Code Playgroud)
问题:未在未保存的记录中设置属性.(new MyModel)->attr是null.更糟糕的是,即使是依赖于此值的其他验证规则也无法访问它,因为在验证之后beforeSave()会调用它.
C)为了确保在验证期间值可用,我们可以改写beforeValidate()方法并在其中设置默认值,如下所示:
public function beforeValidate() {
if ($this->isNewRecord) {
$this->attr = 'defaultValue';
}
return parent::beforeValidate();
}
Run Code Online (Sandbox Code Playgroud)
问题:尚未在未保存(未经验证)的记录中设置属性.$model->validate()如果我们想获得默认值,我们至少需要调用.
D)用于DefaultValidator在rules()验证期间设置默认属性值,如下所示:
public function rules() {
return [
[
'attr', 'default',
'value' => 'defaultValue',
'on' => 'insert', // instantiate model with this scenario
],
// ...
];
}
Run Code Online (Sandbox Code Playgroud)
问题:与B)和C)相同.在我们实际保存或验证记录之前,不会设置值.
那么设置默认属性值的正确方法是什么?没有概述的问题还有其他方法吗?
Coz*_*Coz 17
有两种方法可以做到这一点.
$model => new Model();
Run Code Online (Sandbox Code Playgroud)
现在$model拥有数据库表中的所有默认属性.
或者在您的规则中,您可以使用:
[['field_name'], 'default', 'value'=> $defaultValue],
Run Code Online (Sandbox Code Playgroud)
现在$model将始终使用您指定的默认值创建.
您可以在此处查看核心验证器的完整列表http://www.yiiframework.com/doc-2.0/guide-tutorial-core-validators.html
我知道它已得到解答,但我会添加我的方法.我有Application和ApplicationSearch模型.在应用程序模型中,我添加init并检查当前实例.如果它的ApplicationSearch我跳过初始化.
public function init()
{
if(!$this instanceof ApplicationSearch)
{
$this->id = hash('sha256', 123);
}
parent::init();
}
Run Code Online (Sandbox Code Playgroud)
同样如下面的@mae评论,您可以检查当前实例中是否存在搜索方法,假设您没有将任何带名称搜索的方法添加到非搜索基础模型中,因此代码变为:
public function init()
{
// no search method is available in Gii generated Non search class
if(!method_exists($this,'search'))
{
$this->id = hash('sha256', 123);
}
parent::init();
}
Run Code Online (Sandbox Code Playgroud)
这是与Yii肿的多功能ActiveRecord的挂断
以我的拙见,最好将表单模型,活动记录和搜索模型拆分为单独的类/子类
为什么不拆分搜索模型和表单模型?
abstract class Creature extends ActiveRecord {
...
}
class CreatureForm extends Creature {
public function init() {
parent::init();
if ($this->isNewRecord) {
$this->number_of_legs = 4;
}
}
}
class CreatureSearch extends Creature {
public function search() {
...
}
}
Run Code Online (Sandbox Code Playgroud)
这种方法的好处是
实际上,在我们最近的项目中,我们使用的搜索模型根本没有从相关的ActiveRecord扩展而来
| 归档时间: |
|
| 查看次数: |
26225 次 |
| 最近记录: |