2011-08-16 6 views
3

私は2,3ヶ月前からYiiで遊んでいて、コードはYiiのように構成しています。モデルを他のモデルのリストにするにはどうすればいいのでしょうか?CModelリストへのYiiの方法(他のCModelリストの有無)は何ですか?

Yiiは概念的にはDAOに非常に近いモデルを持っているようですが、MVC設計は非DAOモデルをモデル以外の場所に置かないようにしています。

2の理由(私はMVCの専門家でない)、リストが良いです:

  • 私は取り組むことができないロジックのかなりの量を持つオブジェクトを持ったときに拡張するCModelListのようなものを探していますの関係(いずれにしてもCActiveRecord要素)
  • リストはタイプとしてロジックに適用できますが、すべてを同時にメモリにロードする必要はなく、ids aいないすべてのモデルは
  • CAttributeCollectionアクティブレコードですので:それだけのようなメモリ内のすべてのオブジェクトをサポートしているので、ND

    サブセットのみをロード配列

  • getRestaurantsAverageRatingByPriceRangeなどの異なるモデル内の同じメソッド:これはOOP内の関数型プログラミングがモードとして急速に成長しているためですLSは、複数の方法

例1

$user = User::model()->findByPk($userID); // get a user 
$restaurantList = $user->getRestaurants(); // get restaurants for that user 

for($i=0;$i<5;$i++) { 
    $this->renderPartial("rating", 
     array("rating" => $restaurantList->getAverageRatingByPriceRange($i)); 
} 

例2(同じリストロジック、異なるベースモデル)

$city = City::model()->findByPk($cityID); // get a city 
$restaurantList = $city->getRestaurants(); // get restaurants for that city 

for($i=0;$i<5;$i++) { 
    $this->renderPartial("rating", 
     array("rating" => $restaurantList->getAverageRatingByPriceRange($i)); 
} 

例3(同じリストのタイプを持っているとベースモデル、別ロジック)

$user = User::model()->findByPk($userID); // get a user 
$restaurantList = $user->getRestaurants(); // get restaurants for that user 


$this->renderPartial("map", 
    array("coord" => $restaurantList->getCoordinatesMap()); 

私は違った考え方をするか、きちんとしたコードと構造を使用して維持するためのメカニズムは何ですか?コンポーネントの動作の

+1

異なるタイプのデータに対して同じメソッドを使用できます。私は主に、関連するデータ(論理ではない)と事前定義されたクエリ/フィルタリングのスコープ(必要に応じて組み合わせることができます)を取得するためにリレーションを使用しますが、ARでオーバーヘッドが発生し、とにかくcreateCommand。 – ldg

+0

ありがとうございました。これまで私がやったことですが、これらのクラスをモデルにしたいと思います。私は、CModelを拡張するCModelListクラスを作成することを考えています。ちょうど私がYiiを間違って取得していないことを確認したい。私のアプリはすでに80%構築されているので、私はリファクタリングを計画しています。 –

+0

私は同様の要件と同じ考えを持っていますが、最後にはCModelの余分なオーバーヘッドがそれに見合うものではないため、カスタムコンポーネントを使い、いくつかのモデルを拡張しました。私は確かにあなたが思いつくものを見て興味があるでしょう。 – ldg

答えて

2

使用

成分はmixinパターンをサポートし、1つまたはいくつかの行動を添付することができます。ビヘイビアとは、特殊化(すなわち、通常のクラス継承)ではなく機能を収集する手段によって、そのメソッドが添付コンポーネントによって「継承」されるオブジェクトです。コンポーネントは、いくつかの振る舞いでアタッチすることができ、したがって、複数の継承を実現します。

動作クラスはIBehaviorインターフェイスを実装する必要があります。ほとんどの動作は、CBehavior基本クラスから拡張できます。ビヘイビアをモデルに追加する必要がある場合は、モデルに追加の機能を実装するCModelBehaviorまたはCActiveRecordBehaviorから拡張することもできます。

ビヘイビアを使用するには、まずそのビヘイビアのattach()メソッドを呼び出すことによってビヘイビアをコンポーネントにアタッチする必要があります。その後、我々は、コンポーネントを介して動作メソッドを呼び出すことができます。

// $name uniquely identifies the behavior in the component 
$component->attachBehavior($name,$behavior); 
// test() is a method of $behavior 
$component->test(); 

取り付け動作は、コンポーネントの通常のプロパティのようにアクセスすることができます。動作名前ツリーが構成要素に接続されている場合、例えば、我々が使用して、この挙動オブジェクトへの参照を取得することができる:

$behavior=$component->tree; 
// equivalent to the following: 
// $behavior=$component->asa('tree'); 

動作は一時的に無効にすることができ、その方法は、コンポーネントを介して利用できないようになっています。たとえば、

$component->disableBehavior($name); 
// the following statement will throw an exception 
$component->test(); 
$component->enableBehavior($name); 
// it works now 
$component->test(); 

同じコンポーネントに関連付けられた2つの動作には、同じ名前のメソッドがある可能性があります。この場合、最初に添付された動作の方法が優先されます。

eventsと一緒に使用すると、ビヘイビアがさらに強力になります。ビヘイビアは、コンポーネントにアタッチされているときに、そのメソッドのいくつかをコンポーネントのいくつかのイベントにアタッチすることができます。そうすることによって、動作はコンポーネントの通常の実行フローを観察または変更する機会を得る。

動作のプロパティは、接続されているコンポーネントを介してアクセスすることもできます。プロパティには、パブリックメンバ変数と、動作のゲッタおよび/またはセッタを介して定義されたプロパティの両方が含まれます。たとえば、ビヘイビアにxyzという名前のプロパティがあり、ビヘイビアがコンポーネント$ aにアタッチされているとします。次に、式$a->xyzを使用してビヘイビアのプロパティにアクセスできます。

もっと読み:
http://www.yiiframework.com/wiki/44/behaviors-events
http://www.ramirezcobos.com/2010/11/19/how-to-create-a-yii-behavior/

あなたはロジックでカスタムクラス(ES)とグループ・メソッドを定義し、そのデータ型に基づいてクエリを作成するクエリビルダ(またはdbCriteria)を使用する場合があります
関連する問題