有关系的模特

时间:2014-05-06 19:33:46

标签: phalcon

我目前正在尝试使用Phalcon作为应用程序的后端服务框架。我非常了解PHP,我听说Phalcon有很多好东西,并决定尝试一下。 我非常喜欢它,虽然我偶然发现了一个似乎无法解决的问题,甚至没有在谷歌上花费最后几个小时(通常这就是诀窍)。

无论如何,我试图定义两个模型之间的关系 - 用户表和国家表。每个用户都有一个国家,但不是相反。 我开始只是在user表中定义一个列作为country表的外键。我在Users模型的初始化方法中使用了hasOne方法,但是在执行$ user-> country->名称时会出现警告。

所以我重新RTFM,重做了表和模型,在用户和国家/地区表之间添加了一个关系表。我目前的表设计是(有点截断 - 我留下了一些非重要的字段):

CREATE TABLE IF NOT EXISTS `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `password` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=2 ;

CREATE TABLE IF NOT EXISTS `countries` (
  `code` varchar(2) COLLATE utf8_unicode_ci NOT NULL,
  `name` varchar(64) COLLATE utf8_unicode_ci NOT NULL,
  PRIMARY KEY (`code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

CREATE TABLE IF NOT EXISTS `users_countries` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `users_id` int(10) NOT NULL,
  `countries_id` varchar(2) COLLATE utf8_unicode_ci NOT NULL,
  PRIMARY KEY (`id`),
  KEY `countries_id` (`countries_id`),
  KEY `users_id` (`users_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=5 ;
ALTER TABLE `users_countries`
  ADD CONSTRAINT `users_countries_ibfk_4` FOREIGN KEY (`countries_id`) REFERENCES `countries` (`code`) ON DELETE CASCADE ON   UPDATE CASCADE,
  ADD CONSTRAINT `users_countries_ibfk_3` FOREIGN KEY (`users_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;

我的PHP模型:

class Users extends \Phalcon\Mvc\Model {
  // Properties here - all public.
  public function initialize() {}
    $this->hasOne('id', 'UserCountries', 'users_id', array('foreignKey' => TRUE));
    $this->hasOne('id', 'UserPictures', 'users_id');
  }
}

class UsersCountries extends \Phalcon\Mvc\Model {
  // Properties here - all public.
  public function initialize() {
    $this->belongsTo('users_id', 'Users', 'id');
    $this->belongsTo('countries_id', 'Countries', 'id');
  }
}

class Countries extends \Phalcon\Mvc\Model { }

因此,想法是用户了解该国家,但该国家对该用户一无所知。

现在,当我创建用户时,我会

$user = new Users;
$user->username = "kaa";
$user->password = "test";
$user->save();

用户创建得很好,但我不知道如何以正确的方式创建与国家的关系。 我能做到:

$country = new UsersCountries;
$country->users_id = $user->id;
$country->countries_id = 'DK';
$country->save();

将关系存储在数据库中,但我无法找到从用户对象访问关系的任何方法。 当我尝试

$user->usersCountries 

我收到异常“未捕获异常'Phalcon \ Mvc \ Model \ Exception',消息'模型'UserCountries'无法加载”

所以在我看来,我有点想念在Phalcon中使用模型之间的这些关系。 任何人都知道如何以正确的方式处理这些关系/知道我可以阅读的地方吗?

2 个答案:

答案 0 :(得分:2)

tl; dr:看起来像拼写错误

看起来您要么在代码中输入错误,因为错误表明Phalcon找不到UserCountries而不是UsersCountries

所以看看你的模特,也许它应该是这样的:

class Users extends \Phalcon\Mvc\Model {
 // Properties here - all public.
  public function initialize() {}
    // typos here?
    $this->hasOne(
        'id',
        'UsersCountries',
        'users_id',
        array('foreignKey' => TRUE)
    );
    $this->hasOne('id', 'UsersPictures', 'users_id');
  }
}

由于'UsersCountries'必须是模型的名称,并且您的课程UsersCountries不是UserCountries

顺便说一句,您可以在定义关系时为模型设置别名:

$this->hasOne('id', 'UsersCountries', 'users_id',
    array('foreignKey' => TRUE, 'alias' => 'UserFlag'));

那么你可以这样称呼它:

$user = Users::findFirst();
$user->UserFlag->Countries;

答案 1 :(得分:1)

您正在为数据库表中的国家/地区的用户使用多对多(n-n)关系,并且当您看起来想要一对多关系时,您的phalcon模型中会建立1-n关系。

实际上,您已经建立了这样一个用户可以拥有任意数量的国家/地区,并且一个国家/地区可以拥有任意数量的用户。如上所述,这不是你想要的。您希望每个用户都有一个国家/地区正确吗?

您可以安全地将用户移至国家/地区表格和模型,只需在您的用户表格中创建一个名为country_id的列,该列将存储该国家/地区的PK。

    class Users extends \Phalcon\Mvc\Model
    {
      public function initialize()
      {
          $this->hasOne('country_id', 'Countries', 'id', array(
              'alias' => 'country'
          ));
      }
    }

然后在您的代码/控制器中,您需要做的就是找到您所在的国家/地区

$user = new User();

// if our countries table has a column named abbreviation, we can use phalcons magic find method to search by that columns name
$user->country = Countries::findFirstByAbbreviation('DK');

$user->create();