Pregunta

Me gustaría saber si es posible crear una relación hasMany en un modelo que utiliza el ID del usuario conectado.

Ejemplo: Un consejo tiene muchas votaciones (de diferentes usuarios). Esto es fácil:

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

Ahora quiero conseguir todos los consejos, pero desea saber si el usuario registra en los has votado este Consejo ya. Así que me gustaría crear un Realtionship que se parece a esto:

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

¿Cómo consigo los $ loggedinUser_id en este modelo? O se trata de una mala manera de implementar este problema? Más bien debería ir a dar un hallazgo independiente en el modelo TipVoting?

¿Alguna idea?

Gracias!

¿Fue útil?

Solución

Usar el comportamiento controlable. http://book.cakephp.org/view/474/Containable

No quiero definir una relación diferente, lo que desea es ser capaz de filtrar por criterios asociados. Contenible le permitirá hacer esto.

Con sólo la relación TipVoting, en su modelo de hacer esto:

var $actsAs = array( 'Containable' );

en su acción de controlador hacer esto:

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

Otros consejos

Si entiendo la pregunta, lo que realmente después es una manera de definir la condición una vez en lugar de una manera de definir una unión específica condición. El comportamiento Containable manejaría este último, pero no el primero. Con ese fin ...

No estoy al tanto de cualquier manera de utilizar valores de las variables en su definición de la combinación. Dado que estos son variables de clase, sospecho que no se puede hacer (disclaimer: no he probado). También tiene la complejidad añadida de tratar de acceder a lo que es normalmente un valor de sesión (el usuario autorizado) a nivel de modelo -. Algo de un MVC no-no en el sentido más estricto

Lo que he hecho para satisfacer necesidades similares es una combinación de cosas es la siguiente:

Yo uso mi AppController a la información del usuario autenticado hacia adelante:

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

En su modelo, crear una devolución de llamada beforeFind() que modificará la estructura de consulta:

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

Este código es sólo un fragmento que satisface una necesidad similares a la suya por lo que no puede trabajar directamente, pero debe darle una idea de lo que es posible y creo que puede ser incluso muy cerca lo que está buscando. Sólo ten en cuenta que es probable que tenga que hacer algunos cambios aquí y allá.

La clave es que se está conservando la estructura "adecuada" MVC mediante el envío de información de la sesión con el modelo de forma explícita (en lugar de pedir el modelo para acceder a ella directamente), mientras que el establecimiento de su condición de consulta para utilizar un valor de sesión cada registros de tiempo de el modelo se recuperan a menos que una condición centrada en el usuario ya está involucrado.

No es un ajuste perfecto para lo que está buscando, pero no debe tomar mucho tiempo para adaptarlo a sus necesidades.

Trate de usar bindModel del 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
                        ...
                    ),
                    ...
                ),
                ...
            ),
        );
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top