Commit fc477860 by Nobuo Kihara

docs/guide-ja/structure-models.md - revised [ci skip]

parent cc395c91
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
モデルクラスは、[[yii\base\Model]] またはその子クラスを拡張することによって作成することが出来ます。 モデルクラスは、[[yii\base\Model]] またはその子クラスを拡張することによって作成することが出来ます。
基底クラス [[yii\base\Model]] は数多くの有用な機能をサポートしています。 基底クラス [[yii\base\Model]] は数多くの有用な機能をサポートしています。
* [属性](#attributes): 業務のデータを表現し、通常のオブジェクトプロパティや配列要素のようにアクセス出来る。 * [属性](#attributes): 業務のデータを表現する。通常のオブジェクトプロパティや配列要素のようにしてアクセス出来る。
* [属性のラベル](#attribute-labels): 属性の表示ラベルを規定する。 * [属性のラベル](#attribute-labels): 属性の表示ラベルを規定する。
* [一括代入](#massive-assignment): 一回のステップで複数の属性にデータを投入することをサポートしている。 * [一括代入](#massive-assignment): 一回のステップで複数の属性にデータを投入することをサポートしている。
* [検証規則](#validation-rules): 宣言された検証規則に基いて入力されたデータを確認する。 * [検証規則](#validation-rules): 宣言された検証規則に基いて入力されたデータを確認する。
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
モデルは業務のデータを *属性* の形式で表現します。 モデルは業務のデータを *属性* の形式で表現します。
全ての属性はそれぞれパブリックにアクセス可能なモデルのプロパティと同様なものです。 全ての属性はそれぞれパブリックにアクセス可能なモデルのプロパティと同様なものです。
メソッド [[yii\base\Model::attributes()]] が、モデルがどのような属性を持つかを規定します。 [[yii\base\Model::attributes()]] メソッドが、モデルがどのような属性を持つかを規定します。
属性に対しては、通常のオブジェクトプロパティにアクセスするのと同じようにして、アクセスすることが出来ます。 属性に対しては、通常のオブジェクトプロパティにアクセスするのと同じようにして、アクセスすることが出来ます。
...@@ -57,7 +57,7 @@ foreach ($model as $name => $value) { ...@@ -57,7 +57,7 @@ foreach ($model as $name => $value) {
### 属性を定義する<a name="defining-attributes"></a> ### 属性を定義する<a name="defining-attributes"></a>
あなたのモデルが [[yii\base\Model]] を直接に拡張するものである場合、既定によって、全ての *static でない public な* メンバ変数は属性となります。 あなたのモデルが [[yii\base\Model]] を直接に拡張するものである場合、既定によって、全ての *static でない public な* メンバ変数は属性となります。
例えば、次に示す `ContactForm` モデルは4つの属性を持ちます: すなわち、`name``email``subject`、そして、`body`す。 例えば、次に示す `ContactForm` モデルは4つの属性、すなわち、`name``email``subject`、そして、`body` を持ちます。
この `ContactForm` モデルは、HTML フォームから受け取る入力データを表現するために使われます。 この `ContactForm` モデルは、HTML フォームから受け取る入力データを表現するために使われます。
```php ```php
...@@ -77,9 +77,9 @@ class ContactForm extends Model ...@@ -77,9 +77,9 @@ class ContactForm extends Model
[[yii\base\Model::attributes()]] をオーバーライドして、属性を異なる方法で定義することが出来ます。 [[yii\base\Model::attributes()]] をオーバーライドして、属性を異なる方法で定義することが出来ます。
このメソッドはモデルの中の属性の名前を返さなくてはなりません。 このメソッドはモデルの中の属性の名前を返さなくてはなりません。
例えば、[[yii\db\ActiveRecord]] はそのようにして、関連付けられたデータベーステーブルのコラム名を属性の名前として返しています。 例えば、[[yii\db\ActiveRecord]] は、関連付けられたデータベーステーブルのコラム名を属性の名前として返すことによって、属性を定義しています。
これと同時に `__get()``__set()` などのマジックメソッドをオーバーライドして これと同時に、定義された属性に対して通常のオブジェクトプロパティと同じようにアクセスすることが出来るように
属性が通常のオブジェクトプロパティと同じようにアクセス出来るようにする必要があるかもしれないことに注意してください。 `__get()``__set()` などのマジックメソッドをオーバーライドする必要があるかもしれないことに注意してください。
### 属性のラベル <a name="attribute-labels"></a> ### 属性のラベル <a name="attribute-labels"></a>
...@@ -101,8 +101,7 @@ echo $model->getAttributeLabel('name'); ...@@ -101,8 +101,7 @@ echo $model->getAttributeLabel('name');
このメソッドは、キャメルケースの変数名を複数の単語に分割し、各単語の最初の文字を大文字にします。 このメソッドは、キャメルケースの変数名を複数の単語に分割し、各単語の最初の文字を大文字にします。
例えば、`username``Username` となり、`firstName``First Name` となります。 例えば、`username``Username` となり、`firstName``First Name` となります。
自動的に生成されるラベルを使用したくない場合は、[[yii\base\Model::attributeLabels()]] をオーバーライドして、 自動的に生成されるラベルを使用したくない場合は、[[yii\base\Model::attributeLabels()]] をオーバーライドして、属性のラベルを明示的に宣言することが出来ます。例えば、
属性のラベルを明示的に宣言することが出来ます。例えば、
```php ```php
namespace app\models; namespace app\models;
...@@ -129,7 +128,7 @@ class ContactForm extends Model ...@@ -129,7 +128,7 @@ class ContactForm extends Model
``` ```
複数の言語をサポートするアプリケーションでは、属性のラベルを翻訳したいと思うでしょう。 複数の言語をサポートするアプリケーションでは、属性のラベルを翻訳したいと思うでしょう。
これも、以下のように、[[yii\base\Model::attributeLabels()|attributeLabels()]] の中で行うことが出来ます: これも、以下のように、[[yii\base\Model::attributeLabels()|attributeLabels()]] の中で行うことが出来ます
```php ```php
public function attributeLabels() public function attributeLabels()
...@@ -147,8 +146,7 @@ public function attributeLabels() ...@@ -147,8 +146,7 @@ public function attributeLabels()
[シナリオ](#scenarios) に基づいて、同じ属性に対して違うラベルを返すことことが出来ます。 [シナリオ](#scenarios) に基づいて、同じ属性に対して違うラベルを返すことことが出来ます。
> Info|情報: 厳密に言えば、属性のラベルは [ビュー](structure-views.md) の一部を成すものです。 > Info|情報: 厳密に言えば、属性のラベルは [ビュー](structure-views.md) の一部を成すものです。
しかし、たいていの場合、モデルの中でラベルを宣言する方が便利が良く、 しかし、たいていの場合、モデルの中でラベルを宣言する方が便利が良く、結果としてクリーンで再利用可能なコードになります。
結果としてクリーンで再利用可能なコードになります。
## シナリオ<a name="scenarios"></a> ## シナリオ<a name="scenarios"></a>
...@@ -160,19 +158,19 @@ public function attributeLabels() ...@@ -160,19 +158,19 @@ public function attributeLabels()
モデルは [[yii\base\Model::scenario]] プロパティを使って、自身が使われているシナリオを追跡します。 モデルは [[yii\base\Model::scenario]] プロパティを使って、自身が使われているシナリオを追跡します。
既定では、モデルは `default` という単一のシナリオのみをサポートします。 既定では、モデルは `default` という単一のシナリオのみをサポートします。
次のコードは、モデルのシナリオを設定する二つの方法を示すものです: 次のコードは、モデルのシナリオを設定する二つの方法を示すものです
```php ```php
// プロパティとしてシナリオをセットする // プロパティとしてシナリオをセットする
$model = new User; $model = new User;
$model->scenario = 'login'; $model->scenario = 'login';
// シナリオはコンフィギュレーションでセットされる // シナリオは設定情報でセットされる
$model = new User(['scenario' => 'login']); $model = new User(['scenario' => 'login']);
``` ```
既定では、モデルによってサポートされるシナリオは、モデルで宣言されている [検証規則](#validation-rules) によって決定されます。 既定では、モデルによってサポートされるシナリオは、モデルで宣言されている [検証規則](#validation-rules) によって決定されます。
しかし、次のように、[[yii\base\Model::scenarios()]] メソッドをオーバーライドして、この動作をカスタマイズすることが出来ます: しかし、次のように、[[yii\base\Model::scenarios()]] メソッドをオーバーライドして、この動作をカスタマイズすることが出来ます
```php ```php
namespace app\models; namespace app\models;
...@@ -201,7 +199,7 @@ class User extends ActiveRecord ...@@ -201,7 +199,7 @@ class User extends ActiveRecord
`scenarios()` の既定の実装は、検証規則の宣言メソッドである [[yii\base\Model::rules()]] に現れる全てのシナリオを返すものです。 `scenarios()` の既定の実装は、検証規則の宣言メソッドである [[yii\base\Model::rules()]] に現れる全てのシナリオを返すものです。
`scenarios()` をオーバーライドするときに、デフォルトのシナリオに加えて新しいシナリオを導入したい場合は、 `scenarios()` をオーバーライドするときに、デフォルトのシナリオに加えて新しいシナリオを導入したい場合は、
次のようなコードを書きます: 次のようなコードを書きます
```php ```php
namespace app\models; namespace app\models;
...@@ -250,9 +248,8 @@ if ($model->validate()) { ...@@ -250,9 +248,8 @@ if ($model->validate()) {
``` ```
モデルに関連付けられた検証規則を宣言するためには、[[yii\base\Model::rules()]] メソッドをオーバーライドして、 モデルに関連付けられた検証規則を宣言するためには、[[yii\base\Model::rules()]] メソッドをオーバーライドして、モデルの属性が満たすべき規則を返すようにします。
モデルの属性が満たすべき規則を返すようにします。 次の例は、`ContactForm` モデルのために宣言された検証規則を示します。
次の例は、`ContactForm` モデルのために宣言された検証規則を示します:
```php ```php
public function rules() public function rules()
...@@ -269,10 +266,10 @@ public function rules() ...@@ -269,10 +266,10 @@ public function rules()
一個の規則は、一個または複数の属性を検証するために使うことが出来ます。 一個の規則は、一個または複数の属性を検証するために使うことが出来ます。
また、一個の属性は、一個または複数の規則によって検証することが出来ます。 また、一個の属性は、一個または複数の規則によって検証することが出来ます。
検証規則をどのように宣言するかについて、更なる詳細は [入力を検証する](input-validation.md) の節を参照してください。 検証規則をどのように宣言するかについて詳細は [入力を検証する](input-validation.md) の節を参照してください。
時として、特定の [シナリオ](#scenarios) にのみ適用される規則が必要になるでしょう。そのためには、下記のように、 時として、特定の [シナリオ](#scenarios) にのみ適用される規則が必要になるでしょう。
規則に `on` プロパティを指定することが出来ます: そのためには、下記のように、規則に `on` プロパティを指定することが出来ます。
```php ```php
public function rules() public function rules()
...@@ -290,8 +287,8 @@ public function rules() ...@@ -290,8 +287,8 @@ public function rules()
`on` プロパティを指定しない場合は、その規則は全てのシナリオに適用されることになります。 `on` プロパティを指定しない場合は、その規則は全てのシナリオに適用されることになります。
現在の [[yii\base\Model::scenario|シナリオ]] に適用可能な規則は *アクティブな規則* と呼ばれます。 現在の [[yii\base\Model::scenario|シナリオ]] に適用可能な規則は *アクティブな規則* と呼ばれます。
属性が検証されるのは、それが `scenarios()` の中でアクティブな属性であると宣言されており、 属性が検証されるのは、それが `scenarios()` の中でアクティブな属性であると宣言されており、かつ、その属性が `rules()`
かつ、`rules()` の中で宣言されている一つまたは複数のアクティブな規則と関連付けられている場合であり、また、そのような場合だけです。 の中で宣言されている一つまたは複数のアクティブな規則と結び付けられている場合であり、また、そのような場合だけです。
## 一括代入<a name="massive-assignment"></a> ## 一括代入<a name="massive-assignment"></a>
...@@ -299,7 +296,7 @@ public function rules() ...@@ -299,7 +296,7 @@ public function rules()
一括代入は、一行のコードを書くだけで、ユーザの入力したデータをモデルに投入できる便利な方法です。 一括代入は、一行のコードを書くだけで、ユーザの入力したデータをモデルに投入できる便利な方法です。
一括代入は、入力されたデータを [[yii\base\Model::$attributes]] に直接に代入することによって、モデルの属性にデータを投入します。 一括代入は、入力されたデータを [[yii\base\Model::$attributes]] に直接に代入することによって、モデルの属性にデータを投入します。
次の二つのコード断片は等価であり、どちらもエンドユーザから送信されたフォームのデータを `ContactForm` モデルの属性に割り当てようとするものです。 次の二つのコード断片は等価であり、どちらもエンドユーザから送信されたフォームのデータを `ContactForm` モデルの属性に割り当てようとするものです。
明らかに、一括代入を使う前者の方が、後者よりも明瞭で間違いも起こりにくいでしょう: 明らかに、一括代入を使う前者の方が、後者よりも明瞭で間違いも起こりにくいでしょう
```php ```php
$model = new \app\models\ContactForm; $model = new \app\models\ContactForm;
...@@ -318,8 +315,8 @@ $model->body = isset($data['body']) ? $data['body'] : null; ...@@ -318,8 +315,8 @@ $model->body = isset($data['body']) ? $data['body'] : null;
### 安全な属性<a name="safe-attributes"></a> ### 安全な属性<a name="safe-attributes"></a>
一括代入は、いわゆる *安全な属性*、すなわち、モデルの現在の [[yii\base\Model::scenario|シナリオ]] 一括代入は、いわゆる *安全な属性*、すなわち、[[yii\base\Model::scenarios()]] においてモデルの現在の [[yii\base\Model::scenario|シナリオ]]
用に [[yii\base\Model::scenarios()]] にリストされている属性に対してのみ適用されます。 のためにリストされている属性に対してのみ適用されます。
例えば、`User` モデルが次のようなシナリオ宣言を持っている場合において、現在のシナリオが `login` であるときは、`username``password` のみが一括代入が可能です。その他の属性はいっさい触れられません。 例えば、`User` モデルが次のようなシナリオ宣言を持っている場合において、現在のシナリオが `login` であるときは、`username``password` のみが一括代入が可能です。その他の属性はいっさい触れられません。
```php ```php
...@@ -332,9 +329,8 @@ public function scenarios() ...@@ -332,9 +329,8 @@ public function scenarios()
} }
``` ```
> Info|情報: 一括代入が安全な属性に対してのみ適用されるのは、どの属性がエンドユーザのデータによって > Info|情報: 一括代入が安全な属性に対してのみ適用されるのは、どの属性がエンドユーザの入力データによって修正されうるかを制御する必要があるからです。
修正されうるかを制御する必要があるからです。 例えば、`User` モデルに、ユーザに割り当てられた権限を決定する `permission` という属性がある場合、
例えば、`User` モデルに、ユーザに割り当てられる権限を決定する `permission` という属性がある場合、
この属性が修正できるのは、管理者がバックエンドのインターフェイスを通じてする時だけに制限したいでしょう。 この属性が修正できるのは、管理者がバックエンドのインターフェイスを通じてする時だけに制限したいでしょう。
[[yii\base\Model::scenarios()]] の既定の実装は [[yii\base\Model::rules()]] に現われる全てのシナリオと属性を返すものです。 [[yii\base\Model::scenarios()]] の既定の実装は [[yii\base\Model::rules()]] に現われる全てのシナリオと属性を返すものです。
...@@ -354,11 +350,11 @@ public function rules() ...@@ -354,11 +350,11 @@ public function rules()
### 安全でない属性<a name="unsafe-attributes"></a> ### 安全でない属性<a name="unsafe-attributes"></a>
上記で説明したように、[[yii\base\Model::scenarios()]] メソッドは二つの目的を持っています: 上記で説明したように、[[yii\base\Model::scenarios()]] メソッドは二つの目的を持っています
すなわち、どの属性が検証されるべきかを決めることと、どの属性が安全であるかを決めることです。 すなわち、どの属性が検証されるべきかを決めることと、どの属性が安全であるかを決めることです。
めったにない場合として、属性を検証する必要はあるが、安全であるという印は付けたくない、ということがあります。 めったにない場合として、属性を検証する必要はあるが、安全であるという印は付けたくない、ということがあります。
そういう時は、下の例の `secret` 属性のように、`scenarios()` の中で宣言するときに属性の名前の前に感嘆符 そういう時は、下の例の `secret` 属性のように、`scenarios()` の中で宣言するときに属性の名前の前に感嘆符
`!` を前置することが出来ます: `!` を前置することが出来ます
```php ```php
public function scenarios() public function scenarios()
...@@ -370,8 +366,7 @@ public function scenarios() ...@@ -370,8 +366,7 @@ public function scenarios()
``` ```
このモデルが `login` シナリオにある場合、三つの属性は全て検証されます。しかし、`username` このモデルが `login` シナリオにある場合、三つの属性は全て検証されます。しかし、`username`
`password` の属性だけが一括代入が可能です。`secret` 属性に入力値を割り当てるためには、 `password` の属性だけが一括代入が可能です。`secret` 属性に入力値を割り当てるためには、下記のように明示的に代入を実行する必要があります。
下記のように明示的に実行する必要があります。
```php ```php
$model->secret = $secret; $model->secret = $secret;
...@@ -384,8 +379,8 @@ $model->secret = $secret; ...@@ -384,8 +379,8 @@ $model->secret = $secret;
Excel 形式に変換したい場合があるでしょう。 Excel 形式に変換したい場合があるでしょう。
エクスポートのプロセスは二つの独立したステップに分割することが出来ます。 エクスポートのプロセスは二つの独立したステップに分割することが出来ます。
最初のステップで、モデルは配列に変換されます。そして第二のステップで、配列が目的の形式に変換されます。 最初のステップで、モデルは配列に変換されます。そして第二のステップで、配列が目的の形式に変換されます。
あなたは最初のステップだけに注力しても構いません。と言うのは、第二のステップは汎用的なデータフォーマッタ、 あなたは最初のステップだけに注力しても構いません。と言うのは、第二のステップは汎用的なデータフォーマッタ、例えば [[yii\web\JsonResponseFormatter]]
例えば [[yii\web\JsonResponseFormatter]] によって達成できるからです。 によって達成できるからです。
モデルを配列に変換する最も簡単な方法は、[[yii\base\Model::$attributes]] プロパティを使うことです。 モデルを配列に変換する最も簡単な方法は、[[yii\base\Model::$attributes]] プロパティを使うことです。
例えば、 例えば、
...@@ -399,23 +394,21 @@ $array = $post->attributes; ...@@ -399,23 +394,21 @@ $array = $post->attributes;
モデルを配列に変換するためのもっと柔軟で強力な方法は、[[yii\base\Model::toArray()]] メソッドを使うことです。 モデルを配列に変換するためのもっと柔軟で強力な方法は、[[yii\base\Model::toArray()]] メソッドを使うことです。
このメソッドの既定の動作は [[yii\base\Model::$attributes]] のそれと同じものです。 このメソッドの既定の動作は [[yii\base\Model::$attributes]] のそれと同じものです。
しかしながら、このメソッドを使うと、どのデータ項目 (*フィールド* と呼ばれます) を結果の配列に入れるか、 しかしながら、このメソッドを使うと、どのデータ項目 (*フィールド* と呼ばれます)
そして、その項目にどのような書式を適用するかを選ぶことが出来ます。 を結果の配列に入れるか、そして、その項目にどのような書式を適用するかを選ぶことが出来ます。
実際、[レスポンスの書式設定](rest-response-formatting.md) で説明されているように、 実際、[レスポンスの書式設定](rest-response-formatting.md) で説明されているように、RESTful
RESTful ウェブサービスの開発においては、これがモデルをエクスポートする既定の方法となっています。 ウェブサービスの開発においては、これがモデルをエクスポートする既定の方法となっています。
### フィールド<a name="fields"></a> ### フィールド<a name="fields"></a>
フィールドとは、単に、モデルの [[yii\base\Model::toArray()]] メソッドを呼ぶことによって取得される配列の中の、 フィールドとは、単に、モデルの [[yii\base\Model::toArray()]] メソッドを呼ぶことによって取得される配列に含まれる名前付きの要素のことです。
名前付きの要素のことです。
既定では、フィールドの名前は属性の名前と等しいものになります。しかし、この既定の動作は、 既定では、フィールドの名前は属性の名前と等しいものになります。しかし、この既定の動作は、[[yii\base\Model::fields()|fields()]]
[[yii\base\Model::fields()|fields()]] および/または [[yii\base\Model::extraFields()|extraFields()]] メソッドをオーバーライドして、変更することが出来ます。 および/または [[yii\base\Model::extraFields()|extraFields()]] メソッドをオーバーライドして、変更することが出来ます。
どちらも、フィールド定義のリストを返すべきメソッドです。 どちらのメソッドも、フィールド定義のリストを返します。
`fields()` によって定義されたフィールドは、デフォルトフィールドです。 `fields()` によって定義されるフィールドは、デフォルトフィールドです。すなわち、`toArray()` はデフォルトでこれらのフィールドを返す、ということを意味します。
すなわち、`toArray()` が、既定ではこれらのフィールドを返すということを意味します。 `extraFields()` メソッドは、`$expand` パラメータによって指定する限りにおいて `toArray()` によって返される追加のフィールドを定義するものです。
`extraFields()` メソッドは、`$expand` パラメータによって指定する限りにおいて `toArray()` によって返され得る、追加のフィールドを定義します。
例として、次のコードは、`fields()` で定義された全てのフィールドと、 例として、次のコードは、`fields()` で定義された全てのフィールドと、
(`extraFields()` で定義されていれば) `prettyName``fullAddress` フィールドを返すものです。 (`extraFields()` で定義されていれば) `prettyName``fullAddress` フィールドを返すものです。
...@@ -424,8 +417,8 @@ $array = $model->toArray([], ['prettyName', 'fullAddress']); ...@@ -424,8 +417,8 @@ $array = $model->toArray([], ['prettyName', 'fullAddress']);
``` ```
`fields()` をオーバーライドして、フィールドを追加、削除、リネーム、再定義することが出来ます。 `fields()` をオーバーライドして、フィールドを追加、削除、リネーム、再定義することが出来ます。
`fields()` の返り値は配列でなければなりません。配列のキーはフィールド名であり、 `fields()` の返り値は配列でなければなりません。配列のキーはフィールド名であり、配列の値は対応するフィールド定義です。
配列の値は対応するフィールド定義です。フィールド定義には、プロパティ/属性の名前か、または、対応するフィールドの値を返す無名関数を使うことが出来ます。 フィールドの定義には、プロパティ/属性 の名前か、または、対応するフィールドの値を返す無名関数を使うことが出来ます。
フィールド名がそれを定義する属性名と同一であるという特殊な場合においては、配列のキーを省略することが出来ます。 フィールド名がそれを定義する属性名と同一であるという特殊な場合においては、配列のキーを省略することが出来ます。
例えば、 例えば、
...@@ -475,30 +468,28 @@ public function fields() ...@@ -475,30 +468,28 @@ public function fields()
要約すると、モデルは、 要約すると、モデルは、
* ビジネスデータを表現する属性を含むことが出来ます; * ビジネスデータを表現する属性を含むことが出来ます
* データの有効性と整合性を保証する検証規則を含むことが出来ます; * データの有効性と整合性を保証する検証規則を含むことが出来ます
* ビジネスロジックを実装するメソッドを含むことが出来ます; * ビジネスロジックを実装するメソッドを含むことが出来ます
* リクエスト、セッション、または他の環境データに直接アクセスするべきではありません。 * リクエスト、セッション、または他の環境データに直接アクセスするべきではありません。
これらのデータは、[コントローラ](structure-controllers.md) によってモデルに注入されるべきです; これらのデータは、[コントローラ](structure-controllers.md) によってモデルに注入されるべきです
* HTML を埋め込むなどの表示用のコードは避けるべきです - 表示は [ビュー](structure-views.md) で行う方が良いです; * HTML を埋め込むなどの表示用のコードは避けるべきです - 表示は [ビュー](structure-views.md) で行う方が良いです
* あまりに多くの [シナリオ](#scenarios) を単一のモデルで持つことは避けましょう。 * あまりに多くの [シナリオ](#scenarios) を単一のモデルで持つことは避けましょう。
大規模で複雑なシステムを開発するときには、たいてい、上記の最後にあげた推奨事項を考慮するのが良いでしょう。 大規模で複雑なシステムを開発するときには、たいてい、上記の最後にあげた推奨事項を考慮するのが良いでしょう。
そういうシステムでは、モデルは数多くの場所で使用され、それに従って、数多くの規則セットやビジネスロジックを含むため、非常に大きくて重いものになり得ます。 そういうシステムでは、モデルは数多くの場所で使用され、それに従って、数多くの規則セットやビジネスロジックを含むため、非常に大きくて重いものになり得ます。
コードの一ヶ所に触れるだけで数ヶ所の違った場所に影響が及ぶため、ついには、モデルのコードの保守が悪夢になってしまうこともよくあります。 コードの一ヶ所に触れるだけで数ヶ所の違った場所に影響が及ぶため、ついには、モデルのコードの保守が悪夢になってしまうこともよくあります。
モデルのコードの保守性を高めるために、以下の戦略をとることが出来ます: モデルのコードの保守性を高めるために、以下の戦略をとることが出来ます
* 異なる [アプリケーション](structure-applications.md)[モジュール](structure-modules.md) * 異なる [アプリケーション](structure-applications.md)[モジュール](structure-modules.md)
によって共有される一連の基底モデルクラスを定義します。 によって共有される一連の基底モデルクラスを定義します。
これらのモデルクラスは、すべてで共通に使用される最小限の規則セットとロジックのみを含むべきです。 これらのモデルクラスは、すべてで共通に使用される最小限の規則セットとロジックのみを含むべきです。
* モデルを使用するそれぞれの [アプリケーション](structure-applications.md) または [モジュール](structure-modules.md) において、 * モデルを使用するそれぞれの [アプリケーション](structure-applications.md) または [モジュール](structure-modules.md)
対応する基底モデルクラスから拡張した具体的なモデルクラスを定義します。 において、対応する基底モデルクラスから拡張した具体的なモデルクラスを定義します。
この具体的なモデルクラスが、そのアプリケーションやモジュールに固有の規則やロジックを含むべきです。 この具体的なモデルクラスが、そのアプリケーションやモジュールに固有の規則やロジックを含むべきです。
例えば、[アドバンストアプリケーションテンプレート](tutorial-advanced-app.md) の中で、 例えば、[アドバンストアプリケーションテンプレート](tutorial-advanced-app.md) の中で、基底モデルクラス `common\models\Post`
基底モデルクラス `common\models\Post` を定義することが出来ます。 を定義することが出来ます。次に、フロントエンドアプリケーションにおいては、`common\models\Post` から拡張した具体的なモデルクラス
次に、フロントエンドアプリケーションにおいては、`common\models\Post` から拡張した具体的なモデルクラス `frontend\models\Post` を定義して使います。また、バックエンドアプリケーションにおいても、同様に、`backend\models\Post` を定義します。
`frontend\models\Post` を定義して使います。
また、バックエンドアプリケーションにおいても、同様に、`backend\models\Post` を定義します。
この戦略を取ると、`frontend\models\Post` の中のコードはフロントエンドアプリケーション固有のものであると保証することが出来ます。 この戦略を取ると、`frontend\models\Post` の中のコードはフロントエンドアプリケーション固有のものであると保証することが出来ます。
そして、フロントエンドのコードにどのような変更を加えても、バックエンドアプリケーションを壊すかもしれないと心配する必要がなくなります。 そして、フロントエンドのコードにどのような変更を加えても、バックエンドアプリケーションを壊すかもしれないと心配する必要がなくなります。
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment