CakePHPの中の他のモデルからhasManyの関係とID
-
26-09-2019 - |
質問
私はログインしているユーザーのIDを利用したモデルでhasManyの関係を作成することが可能であるかどうかを疑問に思ってます。
例: 一つの先端は、(異なるユーザからの)多くのvotingsを持っています。これは簡単です:
public $hasMany = array(
'TipVoting' => array(
'className' => 'TipVoting',
'foreignKey' => 'tip_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
));
今、私はすべてのヒントを取得したいが、ユーザーHASTログインは既にこのヒントに投票するかどうかを知りたいです。私はこのようになりますRealtionshipを作成したいと考えてます:
public $hasMany = array(
'MyTipVoting' => array(
'className' => 'TipVoting',
'foreignKey' => 'tip_id',
'dependent' => false,
'conditions' => array('TipVoting.user_id' => $loggedinUser_id),
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
);
どのように私は、このモデルに$ loggedinUser_idを得るのですか?それともこれは、この問題を実装の悪い方法ですか?私はむしろTipVotingモデルに別々の検索のために行くべきでしょうか?
任意のアイデア?
ありがとうございます。
解決
収容可能振る舞いを使用してください。 http://book.cakephp.org/view/474/Containableする
あなたはちょうど関連する基準によってフィルタにできるようにしたい、別の関係を定義する必要はありません。収容可能で、あなたがこれを行うことができるようになります。
ちょうどTipVotingの関係では、あなたのモデルでこれを行います。
var $actsAs = array( 'Containable' );
あなたのコントローラのアクションでは、次の操作を行います。
$this->TipVoting->find( 'all', array(
'contain' => array(
'Vote' => array(
'conditions' => array(
'TipVoting.user_id' => $this->Auth->User('id') ),
'order' => 'TipVoting.id DESC' ) ) );
他のヒント
は、何をした後、実際にしていることは、のの後ではなく、参加する固有の条件を定義する方法の条件を定義する方法です。 Containable
の動作は、後者が、前者ではないを扱うでしょう。そのために...
私はあなたの参加定義で変数の値を使用する方法を認識していませんよ。これらは、クラス変数なので、私はそれを行うことができないと思われる(免責事項:私は試していません)。あなたもモデルレベルで通常セッション値(正規ユーザ)であるものをアクセスしようとしての追加複雑さを持っている - 。厳密な意味でのMVCの何かノーノー
私は同様のニーズを満たすためにやったことは物事の組み合わせでは、以下の通りである:
私は、認証されたユーザ情報を転送するために、私のAppController
を使用します
# AppController
# You may or may not want to use the conditional
if( !empty( $this->data ) ) {
$this->data['User'] = $this->Auth->user();
}
あなたのモデルでは、クエリの構造を変更しますbeforeFind()
コールバックを作成します:
# Your model, e.g. TipVoting
# The data[] array will probably be keyed differently
public function beforeFind( $query ) {
if( array_key_exists( 'active', $this->_schema ) ) {
$conditions = !empty( $query['conditions'] ) ? $query['conditions'] : array();
if( !is_array( $conditions ) ) {
$conditions = array( $conditions );
}
if( !isset ( $conditions['user_id'] ) && !isset( $conditions[$this->alias . '.user_id'] ) ) {
$conditions[$this->alias . '.user_id'] = $this->data['User']['Administrator'];
}
$query['conditions'] = $conditions;
}
return $query;
}
このコードは、それが直接に動作しない可能性があり、それはあなたが可能だかのアイデアを与える必要があり、私はそれもかなり近いかもしれないと思うので、あなたに必要なの似たのを満たしているだけでスニペットです何を後にしています。ちょうどあなたがおそらくここにいくつかの変更を加える必要がありとなりますので注意してあります。
キーは、毎回レコードからセッション値を使用するように、クエリの条件を設定しながら、あなたは(それが直接ではなく、アクセスにモデルを求めて)明示的にモデルにセッション情報を転送することによって、「適切な」MVCの構造を保持しているということですユーザ中心の条件が既に関与しなければ、モデルが取得されます。
それはあなたが後にしている何のためにぴったりではないのですが、それはあなたのニーズに合わせるためにあまりにも長い間それを取るべきではありません。
appControllersのbeforeFilterからbindModelを使用してみてください。
...
public function beforeFilter( ){
parent::beforeFilter( );
if( $this->Auth->user( )){
$this->User->bindModel(
'hasMany' => array(
'MyTipVoting' => array(
'className' => 'TipVoting',
'foreignKey' => 'tip_id',
'conditions' => array(
'MyTipVoting.user_id' => $this->Auth->user( 'id' ),
//note the use of the aliased name here, not TipVoting but MyTipVoting
...
),
...
),
...
),
);
}
}