Question

Je me demande s'il est possible de créer une relation hasMany dans un modèle qui utilise l'ID de l'utilisateur connecté.

Exemple: Une astuce a beaucoup de votations (de différents utilisateurs). C'est facile:

public $hasMany = array(
   'TipVoting' => array(
        'className' => 'TipVoting',
        'foreignKey' => 'tip_id',
        'dependent' => false,
        'conditions' => '',
        'fields' => '',
        'order' => '',
        'limit' => '',
        'offset' => '',
        'exclusive' => '',
        'finderQuery' => '',
        'counterQuery' => ''
    ));

Maintenant, je veux obtenir tous les conseils, mais veulent savoir si le connecté hast utilisateur voté ce Astuce déjà. Donc, je voudrais créer un Realtionship qui ressemble à ceci:

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' => ''
    )
);

Comment puis-je obtenir le loggedinUser_id $ dans ce modèle? Ou est-ce une mauvaise façon de mettre en œuvre cette question? Dois-je aller plutôt pour une découverte séparée sur le modèle TipVoting?

Toutes les idées?

Merci!

Était-ce utile?

La solution

Utilisez le comportement maîtrisable. http://book.cakephp.org/view/474/Containable

Vous ne voulez pas définir une relation différente, vous voulez juste être en mesure de filtrer selon les critères associés. Containable vous permettra de le faire.

Avec juste la relation TipVoting, dans votre modèle procédez comme suit:

var $actsAs = array( 'Containable' );

dans votre action de contrôleur faire ceci:

$this->TipVoting->find( 'all', array( 
 'contain' => array( 
   'Vote' => array( 
    'conditions' => array( 
      'TipVoting.user_id' => $this->Auth->User('id') ), 
    'order' => 'TipVoting.id DESC' ) ) );

Autres conseils

Si je comprends bien la question, ce que vous êtes vraiment après une façon de définir la condition une fois plutôt que d'une façon de définir une condition spécifique à rejoindre. Le comportement Containable traiterait ce dernier, mais pas le premier. À cette fin ...

Je ne suis pas au courant d'aucune façon d'utiliser des valeurs variables dans votre définition se joindre. Puisque ce sont des variables de classe, je pense qu'il ne peut pas être fait (disclaimer: Je ne l'ai pas essayé). Vous avez également la complexité supplémentaire d'essayer d'accéder à ce qui est normalement une valeur de session (l'utilisateur autorisé) au niveau du modèle -. Quelque chose d'un MVC non-non dans le sens le plus strict

Ce que je l'ai fait pour répondre aux besoins similaires est une combinaison de choses est la suivante:

J'utilise mon AppController à info utilisateur authentifié avant:

# AppController
# You may or may not want to use the conditional
if( !empty( $this->data ) ) {
  $this->data['User'] = $this->Auth->user();
}

Dans votre modèle, créez un rappel beforeFind() qui modifiera la structure de la requête:

# 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;
}

Ce code est juste un extrait qui répond à un besoin similaire à la vôtre de sorte qu'il ne fonctionne pas directement, mais il devrait vous donner une idée de ce qui est possible et je pense qu'il peut même être assez proche de ce que vous êtes après. Sachez simplement que vous aurez probablement devoir faire quelques changements ici et là.

La clé est que vous en conservant la « bonne » la structure MVC en transmettant des informations de session au modèle explicitement (plutôt que de demander le modèle pour y accéder directement) tout en fixant votre condition de requête à utiliser une valeur de session tous les enregistrements de temps de le modèle sont récupérés à moins d'une condition centrée sur l'utilisateur est déjà impliqué.

Ce n'est pas un ajustement parfait pour ce que vous êtes après, mais il ne devrait pas prendre trop de temps pour l'adapter à vos besoins.

Essayez d'utiliser bindModel du appControllers beforeFilter.

...
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
                        ...
                    ),
                    ...
                ),
                ...
            ),
        );
    }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top