3

私は最初のアプリケーションをYii(v1.1.12)で作成していますが、学習曲線が少し急なので、助けが必要です。

次の表(およびそれらの関係)を想像してみてください。

  • 詳細(n:1)ドキュメント
  • ドキュメント(n:1)ユーザー
  • ユーザー(n:1)部門
  • ドキュメント(n:1)カテゴリ

userログインしてアプリケーションを使用できるユーザーに関する情報を保持するテーブルです。

私は( Giiを使用してハッキングして)すべてのドキュメントを一覧表示するビューをまとめることができました。また、グリッドにカテゴリIDの代わりにカテゴリ名を表示することもできました。

実装したい機能の1つは、ユーザーがビューを切り替えて、(a)ログインしたユーザーに関連するドキュメントのみが一覧表示されるようにするか、(b)自分の部門に関連するドキュメントのみが一覧表示されるようにすることです。

運が悪かったので少し見回しました。誰か助けてもらえますか?

乾杯、ジョージ

更新:Currenltyを使用してドキュメントのリストを表示しますzii.widgets.grid.CGridView

更新2:Omarの参照に続いて、このURLの主題についてもう少し詳しく説明しているCDbCriteriaことがわかりました。

私は次のモデルコードを思いつきました。これは正常に機能します。

public function searchByUser($user_id)
{
   $criteria=new CDbCriteria;
   $criteria->condition = " user_id = ".$user_id;
   return new CActiveDataProvider($this, array(
          'criteria'=>$criteria,
   ));
}
public function searchByDepartment($user_id)
{
   $criteria=new CDbCriteria;
   $criteria->alias="p";
   $criteria->join = "JOIN (SELECT u.id 
                              FROM user u 
                             INNER JOIN user uu 
                                ON u.department_id = uu.department_id 
                             WHERE uu.id = ".$user_id.") uu 
                                ON p.user_id = uu.id";                  
    return new CActiveDataProvider($this, array('criteria'=>$criteria,));
}

上記は期待どおりに機能しますが、切り刻まれたSQLコードをまったく記述しなくてもよいソリューションを望んでいました。怠惰によるものではなく、フレームワークの機能をさらに活用するためです。

このアプローチはベストプラクティスに従わないと感じています(?)。

4

3 に答える 3

2

独自の条件を作成し、CDBCriteriaその中の条件を定義して、データプロバイダーとしてグリッドビューに渡すようにしてください。

グリッドビュー内での検索を許可した場合は、条件を検索関数に渡し、その中で、渡された基準を検索内の基準とマージします。

于 2012-11-12T18:36:41.073 に答える
2

あなたはあなたが求めているものを達成するために関係を使うことができます。たとえば、特定のユーザーのすべてのドキュメントと部門を表示するには、最初にそのユーザーのリレーションを設定する必要があります。この場合、ユーザーモデルを次のように設定できます。

public function relations()
{
    return array(
        'documents' => array(self::HAS_MANY, 'Document', 'user_id'),
        'department' => array(self::HAS_ONE, 'Department', 'department_id'),
    );
}

次に、次のように現在のユーザーのすべてのドキュメントをプルできます。

$user = User::model()->findByPk($userId);
$documents = $user->documents;

$documentsこれにより、すべてのユーザードキュメントのアクティブなモデルの配列になります。

そのユーザー部門のすべてのドキュメントを取得するには、いくつかのオプションがあります。次のようにDepartmentモデルに追加して、リレーションを再度使用できます。

public function relations()
{
    return array(
        'users' => array(self::HAS_MANY, 'User', 'department_id'),
        'documents' => array(self::HAS_MANY, 'Document', 'document_id', 'through'=>'users'),
    );
}

これにより、すべての部門のドキュメントをそのようにプルできるようになります。

$department = Department::model()->findByPk($departmentId);
$documents = $department->documents;

つまり、次のようにユーザー部門のドキュメントを取得できるということです。

$user = User::model()->findByPk($userId);
$documents = $user->department->documents;

ユーザーモデルのリレーションを使用してそれらを取得するより効率的な方法があるかもしれませんが、私が今それを実行するには遅すぎます;)

アクティブなレコードモデルの配列を取得したら、 CArrayDataProviderを使用して、いつでもそれらをデータプロバイダーに渡すことができます。

$dataprovider = new CArrayDataProvider($documents);

ちなみに私はそれらのどれもテストしていませんので、それらはいくつかの編集が必要かもしれません!

于 2012-11-12T21:57:25.133 に答える
0

適切なモデルで関数を変更する必要がありますsearch(これから推測しdocumentsます)。使用できるコードはすでにそこに表示されています。

コントローラーから渡すことができる検索関数自体にいくつかのパラメーターを追加します。次に、これらを使用して、compare発信する呼び出しを決定します。

于 2012-11-12T15:17:24.973 に答える