これは些細な疑問のように思えるかもしれませんが、私が考えることができる明らかな解決策のすべてには独自の欠陥があります。Yii2:ActiveRecordでデフォルトの属性値を設定する方法は?
私たちが望むのは、検証前と検証中に読み取り可能にし、検索に使用される派生クラスを妨げないように、新しいレコードに対してのみデフォルトのActiveRecord属性値を設定できることです。
デフォルト値は、(new MyModel)->attr
がデフォルトのattr
の値を返すように、クラスをインスタンス化するとすぐに設定して準備する必要があります。
A)
MyModel
オーバーライドinit()
方法ではとisNewRecord
がそうのような真の場合、デフォルト値を割り当てます:ここでは可能性と、彼らが持っている問題のいくつかはある
public function init() { if ($this->isNewRecord) { $this->attr = 'defaultValue'; } parent::init(); }
問題:検索。
MySearchModel
の既定の属性を明示的に設定しない限り(忘れやすいのでエラーが発生しやすい)、派生したMySearchModel
クラスのsearch()
を呼び出して検索を妨げる前に値を設定します(attr
属性は既に設定されています)。検索で間違った結果が返されます)。 Yii1.1では、search()
を呼び出す前にunsetAttributes()
を呼び出して解決しましたが、Yii2ではそのようなメソッドは存在しません。MyModel
オーバーライドbeforeSave()
方法においてB)ようなので:
public function beforeSave($insert) { if ($insert) { $this->attr = 'defaultValue'; } return parent::beforeSave(); }
問題:項目は保存されていないレコードに設定されていません。
(new MyModel)->attr
はnull
です。さらに悪いことに、この値に依存する他の検証規則でさえ、が検証後にと呼ばれているため、この値にアクセスすることはできません。C)値は、我々が代わりに
beforeValidate()
メソッドをオーバーライドして、そのようにそこデフォルト値を設定することができ、検証時に利用可能であることを確認するには、次のpublic function beforeValidate() { if ($this->isNewRecord) { $this->attr = 'defaultValue'; } return parent::beforeValidate(); }
問題:属性はまだで設定されていません保存されていない(未検証の)レコード。デフォルト値を取得する場合は、少なくとも
$model->validate()
に電話する必要があります。 Bと同じ)およびC):public function rules() { return [ [ 'attr', 'default', 'value' => 'defaultValue', 'on' => 'insert', // instantiate model with this scenario ], // ... ]; }
問題:そう等検証中に、デフォルトの属性値を設定する
D)
rules()
で使用DefaultValidator
。実際にレコードを保存または検証するまで、値は設定されません。
だから何がは、デフォルトの属性値を設定するための正しい方法ですか?説明されている問題がなければ他の方法はありますか?
$ model = new DatabaseTable(); $ modelはデータベーステーブルのすべてのデフォルト属性を持っています。 – Coz
@Coz Nopeは、現在のユーザIDなどの動的な属性に対しては機能しません。 – mae
それは、ちょうどカスタムコールバックを使用します。しかし、現在のユーザーIDを使用する場合は、代わりにhttp://www.yiiframework.com/doc-2.0/yii-behaviors-blameablebehavior.htmlを使用してください。 – Coz