我目前正在尝试使用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中使用模型之间的这些关系。 任何人都知道如何以正确的方式处理这些关系/知道我可以阅读的地方吗?
答案 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();