FuelPHP ORM无法插入相关表

Posted

技术标签:

【中文标题】FuelPHP ORM无法插入相关表【英文标题】:FuelPHP ORM cannot insert related table 【发布时间】:2013-12-23 12:58:39 【问题描述】:

我的数据库:

CREATE TABLE IF NOT EXISTS `ws_accounts` (
  `account_id` int(11) NOT NULL AUTO_INCREMENT,
  `account_username` varchar(255) DEFAULT NULL COMMENT 'username',
  `account_email` varchar(255) DEFAULT NULL COMMENT 'email',
  `account_salt` varchar(255) DEFAULT NULL COMMENT 'store salt for use when hashing password',
  `account_password` tinytext COMMENT 'password',
  `account_display_name` varchar(255) DEFAULT NULL COMMENT 'name for display on web to prevent show username.',
  `account_firstname` varchar(255) DEFAULT NULL COMMENT 'first name',
  `account_middlename` varchar(255) DEFAULT NULL COMMENT 'middle name',
  `account_lastname` varchar(255) DEFAULT NULL COMMENT 'last name',
  `account_birthdate` date DEFAULT NULL COMMENT 'birthdate store in date format (YYYY-mm-dd)',
  `account_avatar` varchar(255) DEFAULT NULL COMMENT 'avatar file. refer from root web without http or domain',
  `account_signature` text COMMENT 'signature. very useful in forum',
  `account_timezone` varchar(30) NOT NULL DEFAULT 'Asia/Bangkok' COMMENT 'see timezone list here http://www.php.net/manual/en/timezones.php',
  `account_language` varchar(10) DEFAULT NULL COMMENT 'framework language shortcode eg: en, th',
  `account_create` bigint(20) DEFAULT NULL COMMENT 'timestamp of account create date',
  `account_create_gmt` bigint(20) DEFAULT NULL COMMENT 'timestamp of account create date in gmt0',
  `account_last_login` bigint(20) DEFAULT NULL COMMENT 'timestamp of last login date',
  `account_last_login_gmt` bigint(20) DEFAULT NULL COMMENT 'timestamp of last login date in gmt0',
  `account_status` int(1) NOT NULL DEFAULT '0' COMMENT '0=disable, 1=enable',
  `account_status_text` varchar(255) DEFAULT NULL COMMENT 'status text for describe why disable.',
  `account_new_email` varchar(255) DEFAULT NULL COMMENT 'store new email waiting for confirmation',
  `account_new_password` varchar(255) DEFAULT NULL COMMENT 'store new password in reset password progress',
  `account_confirm_code` varchar(255) DEFAULT NULL COMMENT 'confirmation code. use for confirm register, change email, reset password',
  `account_confirm_code_since` bigint(20) DEFAULT NULL COMMENT 'confirm code generated since',
  PRIMARY KEY (`account_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COMMENT='contain user account' AUTO_INCREMENT=2 ;

--
-- Dumping data for table `ws_accounts`
--

INSERT INTO `ws_accounts` (`account_id`, `account_username`, `account_email`, `account_salt`, `account_password`, `account_display_name`, `account_firstname`, `account_middlename`, `account_lastname`, `account_birthdate`, `account_avatar`, `account_signature`, `account_timezone`, `account_language`, `account_create`, `account_create_gmt`, `account_last_login`, `account_last_login_gmt`, `account_status`, `account_status_text`, `account_new_email`, `account_new_password`, `account_confirm_code`, `account_confirm_code_since`) VALUES
(0, 'Guest', 'none@localhost', NULL, NULL, 'Guest', NULL, NULL, NULL, NULL, NULL, NULL, 'Asia/Bangkok', NULL, 1387121127, 1387095927, NULL, NULL, 0, 'This account is for guest actions.', NULL, NULL, NULL, NULL),
(1, 'admin', 'admin@localhost.com', NULL, '$P$FPnwJAQzX498tYCbbIfYTbdYiOCShE0', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Asia/Bangkok', NULL, 1387121127, 1387095927, NULL, NULL, 1, NULL, NULL, NULL, NULL, NULL);

CREATE TABLE IF NOT EXISTS `ws_account_level` (
  `level_id` int(11) NOT NULL AUTO_INCREMENT,
  `level_group_id` int(11) NOT NULL,
  `account_id` int(11) NOT NULL,
  PRIMARY KEY (`level_id`),
  KEY `level_group_id` (`level_group_id`),
  KEY `account_id` (`account_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

CREATE TABLE IF NOT EXISTS `ws_account_level_group` (
  `level_group_id` int(11) NOT NULL AUTO_INCREMENT,
  `level_name` varchar(255) DEFAULT NULL,
  `level_description` text,
  `level_priority` int(5) NOT NULL DEFAULT '1' COMMENT 'lower is more higher priority',
  PRIMARY KEY (`level_group_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COMMENT='contain user role or level' AUTO_INCREMENT=5 ;

--
-- Dumping data for table `ws_account_level_group`
--

INSERT INTO `ws_account_level_group` (`level_group_id`, `level_name`, `level_description`, `level_priority`) VALUES
(1, 'Super administrator', 'For site owner or super administrator.', 1),
(2, 'Administrator', NULL, 2),
(3, 'Member', 'For registered user.', 999),
(4, 'Guest', 'For non register user.', 1000);

型号

class Model_Accounts extends \Orm\Model 



    protected static $_table_name = 'accounts';
    protected static $_primary_key = array('account_id');
    
    // relations
    protected static $_has_many = array(
        'account_level' => array(
            'model_to' => 'Model_AccountLevel',
            'key_from' => 'account_id',
            'key_to' => 'account_id',
            'cascade_delete' => true,
        ),
        'account_fields' => array(
            'model_to' => 'Model_AccountFields',
            'key_from' => 'account_id',
            'key_to' => 'account_id',
            'cascade_delete' => true,
        ),
    );


model/accounts.php

class Model_AccountLevelGroup extends \Orm\Model 



    protected static $_table_name = 'account_level_group';
    protected static $_primary_key = array('level_group_id');
    
    // relations
    protected static $_has_many = array(
        'account_level' => array(
            'model_to' => 'Model_AccountLevel',
            'key_from' => 'level_group_id',
            'key_to' => 'level_group_id',
            'cascade_delete' => true,
        )
    );



model/accountlevelgroup.php

class Model_AccountLevel extends \Orm\Model 



    protected static $_table_name = 'account_level';
    protected static $_primary_key = array('level_id');
    
    // relations
    protected static $_belongs_to = array(
        'account_level_group' => array(
            'model_to' => 'Model_AccountLevelGroup',
            'key_from' => 'level_group_id',
            'key_to' => 'level_group_id',
        ),
        'accounts' => array(
            'model_to' => 'Model_Accounts',
            'key_from' => 'account_id',
            'key_to' => 'account_id',
        )
    );



model/accountlevel.php


创建用户。

我在帐户模型中使用注册方法来创建用户。

$data['account_username'] = 'unique_username';
$data['account_password'] = 'pass';
$data['account_email'] = 'no@email.tld';

$account = self::forge($data);
$account->account_level = new Model_AccountLevel();
$account->account_level->level_group_id = 3;
$account->save();
$account_id = $account->account_id;

我得到了这个错误。

分配的关系必须是数组或空,给定的关系 account_level 的值无效。

如何插入相关表?我的代码有什么问题?

【问题讨论】:

account_level 被定义为 has_many.. 这意味着它必须是一个集合。 $account->account_level[] = new Model_AccountLevel();。追加,不要设置。 【参考方案1】:

您的account_level 关系是has_many,这意味着在访问它时您需要像访问数组一样访问它。 ORM 期望 this 的值是一个数组,因此直接将模型分配给它是无效的。

你想做的是:

$account->account_level[] = new Model_AccountLevel(['level_group_id' => 3]);

(在构造函数中使用数组,因为我个人觉得它更整洁,但不是必需的)

【讨论】:

以上是关于FuelPHP ORM无法插入相关表的主要内容,如果未能解决你的问题,请参考以下文章

FuelPHP ORM - 未找到属性

仅缓存 FuelPHP ORM 结果中的关系数据

Fuelphp ORM添加到模型属性时出现意外结果

使用 FuelPHP 从 ORM 返回 _data 数组

FuelPHP的orm和mysql不区分大小写`like`

如何为fuelphp ORM关系设置动态条件