2009-03-12 12 views
20

Estoy jugando con Zend Framework e intento utilizar la guía "QuickStart" contra un sitio web que estoy haciendo solo para ver cómo funcionaría el proceso. Perdónenme si esta respuesta es obvia, con suerte alguien con experiencia puede arrojar algo de luz sobre esto.Modelado de objetos con múltiples relaciones de tabla en Zend Framework

Tengo tres tablas de bases de datos:

CREATE TABLE `users` (
    `id` int(11) NOT NULL auto_increment, 
    `email` varchar(255) NOT NULL, 
    `username` varchar(255) NOT NULL default '', 
    `first` varchar(128) NOT NULL default '', 
    `last` varchar(128) NOT NULL default '', 
    `gender` enum('M','F') default NULL, 
    `birthyear` year(4) default NULL, 
    `postal` varchar(16) default NULL, 
    `auth_method` enum('Default','OpenID','Facebook','Disabled') NOT NULL default 'Default', 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `email` (`email`), 
    UNIQUE KEY `username` (`username`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1 

CREATE TABLE `user_password` (
    `user_id` int(11) NOT NULL, 
    `password` varchar(16) NOT NULL default '', 
    PRIMARY KEY (`user_id`), 
    UNIQUE KEY `user_id` (`user_id`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1 

CREATE TABLE `user_metadata` (
    `user_id` int(11) NOT NULL default '0', 
    `signup_date` datetime default NULL, 
    `signup_ip` varchar(15) default NULL, 
    `last_login_date` datetime default NULL, 
    `last_login_ip` varchar(15) default NULL, 
    PRIMARY KEY (`user_id`), 
    UNIQUE KEY `user_id` (`user_id`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1 

Quiero crear un modelo de usuario que utiliza las tres tablas en ciertas situaciones. Por ejemplo, se accede a la tabla de metadatos si/cuando se necesitan los metadatos. Se accede a la tabla user_password solo si se establece el valor predeterminado 'auth_method'. Es probable que agregue una tabla de perfil más adelante a la que me gustaría poder acceder desde el modelo de usuario.

¿Cuál es la mejor manera de hacer esto con ZF y por qué?

+0

Muy poco claro sobre por qué se rechaza esta votación: ¿hay algún problema con esta pregunta? No pude encontrar una pregunta similar que explique esto en los detalles que estoy buscando. Avíseme si puedo ser más claro. –

+0

Dunno, ¿exceso de datos quizás? Podría reemplazar todo ese SQL con una breve descripción de las tablas. – vartec

+0

Parece que alguien votó negativamente todas las preguntas nuevas – vartec

Respuesta

23
class Users extends Zend_Db_Table_Abstract 
{ 
    protected $_name = 'users'; 
    protected $_rowClass = 'User'; 
    protected $_dependentTables = array ('UserMetadata', 'UserPassword'); 

... 

class UserMetadata extends Zend_Db_Table_Abstract 
{ 
    protected $_name = 'user_metadata'; 
    protected $_referenceMap = array (
    'Users'=> array (
    'columns'=>'user_id', 
    'refTableClass'=>'Users', 
    'refColumns'=>'id' 
    ) 
    ); 

... 

class UserPassword extends Zend_Db_Table_Abstract 
{ 
    protected $_name = 'user_password'; 
    protected $_referenceMap = array (
    'Users'=> array (
    'columns'=>'user_id', 
    'refTableClass'=>'Users', 
    'refColumns'=>'id' 
    ) 
    ); 

datos Obtención:

$id = //get your user id from somewhere 

$users = new Users(); 
$user = $users->fetchRow('id=?', $id); 
if ($user->authMethod == 0) 
{ 
    $metadata = $user->findDependentRowset('UserMetadata')->current(); 
} 

o

$user = $users->fetchRow($users->select() 
       ->where('gender=?, 'M') 
       ->order('email ASC'); 

... etc.

datos Inserción:

$newRow = $users->fetchNew(); 
$newRow->email = [email protected]; 
$newRow->save(); 

o

$users = new Users(); 
$data = array('email'  => '[email protected]', 
       'firstname' => 'Me'); 
$users->insert($data); 

Actualización:

$user->email = '[email protected]'; 
$user->save(); 

Eliminación de una fila:

$user->delete(); 

utilizando la transacción:

$db->beginTransaction(); 
$db->commit(); 
$db->rollback(); 

etc ... todo en el ZF Manual!

+0

Esto tiene más sentido para mí, entonces, ¿cómo manejas una inserción en la tabla de usuarios? Lógicamente, también debería haber una fila user_metadata creada. ¿Puedo manejar eso en el nivel de modelo de alguna manera? –

+1

Las lógicas para crear una fila de metadatos al crear una fila de usuario debe escribir usted mismo. pero eso es fácil si quieres hacerlo de la manera más limpia usa transacciones ... – markus

+0

Esto es exactamente lo que terminé haciendo, y funcionó bastante bien. Gracias. –

2

Básicamente, en lugar de usar Zend_Db_Table utilice más Zend_Db_Select o Zend_Db_Statement para recuperar datos.

BTW. Es posible que desee acceder a datos de contraseña no directamente en el modelo de usuario, sino en su clase de autenticación de usuario derivada de Zend_Auth_Adapter.

+0

No planeo acceder a datos de contraseña a través del modelo de usuario, excepto para actualizarlo. ¿No utiliza Zend_Db_Select eludir completamente la idea de modelar datos de usuario como un solo objeto? –

+0

No es ORM, no hay necesidad de mapeo de tablas de clases 1-a-1. – vartec

+0

BTW. el mapeo 1 = 1 sería posible si su DB estuviera en 3NF, su problema proviene del hecho de que desnormalizó su base de datos, dividiendo datos de usuario en 3 tablas. – vartec

0

Yo diría que la mejor manera de hacer esto con ZF es usando Doctrine.

0

Sólo unas pocas notas inmediatamente el palo:

La primera tabla del usuario, se parece más a una mesa persona, excepto por el método de autenticación, pero se puede poner que en la tabla user_password, que probablemente podría cambiar el nombre Usuario. La tabla User_Metadata parece que podría fusionarse con la tabla User_Password/User.

Ahora, incluso sin esos cambios, tiene tres tablas distintas, con tres conceptos distintos, si modela cada una de esas clases separadas como diferentes, y luego tenía una clase UserModel como una especie de fachada para acceder a cada una, lo haría probablemente lo haga más fácil.

2

En resumen, crearía un modelo para cada mesa, no un modelo que tenga acceso a las tres. Me gustaría entonces define relationships entre las tablas.

Para ser sincero, no parece muy "SECO" tener que crear un modelo para cada tabla, pero eso es lo que veo repetidamente en varios ejemplos en línea y es lo que he hecho en los pocos proyectos que creado con Zend Framework. Si alguien tiene una mejor manera de manejar esto, espero que lo publique aquí.

Cuestiones relacionadas