Моделирование объектов с несколькими связями таблиц в Zend Framework - PullRequest
20 голосов
/ 12 марта 2009

Я играю с Zend Framework и пытаюсь использовать руководство "QuickStart" для веб-сайта, который я создаю, просто чтобы посмотреть, как этот процесс будет работать. Простите, если этот ответ очевиден, надеюсь, кто-то опытный сможет пролить свет на это.

У меня есть три таблицы базы данных:

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

Я хочу создать модель User, которая использует все три таблицы в определенных ситуациях. Например, к таблице метаданных осуществляется доступ, если / когда нужны метаданные. Доступ к таблице user_password возможен только в том случае, если задан auth_method по умолчанию. Скорее всего, позже я добавлю таблицу профилей, к которой я хотел бы получить доступ из пользовательской модели.

Каков наилучший способ сделать это с ZF и почему?

Ответы [ 5 ]

23 голосов
/ 13 марта 2009
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'
    )
    );

Выборка данных:

$id = //get your user id from somewhere

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

или

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

... и т. Д.

Вставка данных:

$newRow = $users->fetchNew();
$newRow->email = me@domain.com;
$newRow->save();

или

$users = new Users();
$data = array('email'     => 'me@domain.com',
              'firstname' => 'Me');
$users->insert($data);

Обновление:

$user->email = 'me@domain.org';
$user->save();

Удаление строки:

$user->delete();

Использование транзакции:

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

и т.д ... все это в руководстве ZF !

2 голосов
/ 13 марта 2009

Короче говоря, я бы создал модель для каждой таблицы, а не одну модель, которая обращается ко всем трем. Затем я определю отношения между таблицами.

Честно говоря, кажется, не очень "СУХОЙ" создавать модель для каждой таблицы, но это то, что я неоднократно делал в различных примерах онлайн, и это то, что я делал в нескольких проектах, которые у меня есть. созданный с Zend Framework. Если у кого-то есть лучший способ справиться с этим, я надеюсь, что он опубликует его здесь.

2 голосов
/ 12 марта 2009

В основном вместо использования Zend_Db_Table используйте более общие Zend_Db_Select или Zend_Db_Statement для извлечения данных.

КСТАТИ. Возможно, вы захотите получить доступ к данным пароля не напрямую в модели пользователя, а в своем классе аутентификации пользователя, полученном из Zend_Auth_Adapter.

0 голосов
/ 12 марта 2009

Всего несколько заметок с места:

Первая таблица User выглядит больше как таблица Person, за исключением метода auth, но вы можете поместить его в таблицу User_Password, которую вы, вероятно, можете переименовать в User. Кажется, что таблица User_Metadata может быть просто объединена с таблицей User_Password / User.

Теперь, даже без этих изменений, у вас есть три отдельных таблицы с тремя различными концепциями, если вы смоделируете каждый из этих отдельных классов как разные классы, а затем имеете класс UserModel в качестве своего рода фасада для доступа к каждому, вероятно сделать это проще.

0 голосов
/ 12 марта 2009

Я бы сказал, что лучший способ сделать это с ZF - использовать Doctrine .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...