【问题标题】:Doctrine relationships教义关系
【发布时间】:2011-04-08 05:45:30
【问题描述】:

我有两张桌子。一个用户表和一个配置文件表。 profile 表有一个外键 users_id。表的模型设置为一对一的关系。当我尝试保存一些数据时,出现此错误:

Fatal error: Uncaught exception 'Doctrine_Connection_Mysql_Exception' with message 'SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'users_id' cannot be null' in

如果我只是将数据保存到 users 表中,那么我知道它是 auto_incrementing 并生成一个新的 id 值。但是,由于某种原因,当我尝试将表链接在一起或调用 $users->id 时,它会返回 NULL 值。

这是我的代码:

$u = new Users();
// Users table.
        $u->username   = $username;
        $u->password   = $password;
        $u->email      = $email;
        $u->groups_id   = $group_id;
        $u->ip_address = $ip_address;
        $u->last_login = now();
        $u->active     = 1;

    if ($this->store_salt)
    {
        $u->salt = $salt;
    }
    $u->save();

    // Profile table.
    $p = new Profile(); 
    $p->first = $additional_data['first'];
    $p->last = $additional_data['last'];
    $p->role = $additional_data['role'];
    $p->Users = $u;
    $p->save(); return;

以下是模型:

 /**
 * BaseUsers
 * 
 * This class has been auto-generated by the Doctrine ORM Framework
    • @property 整数 $id
    • @property 字符串 $username
    • @property 字符串 $password
    • @property 字符串 $ip_address
    • @property 日期 $created_at
    • @property 日期 $updated_at
    • @property 字符串 $salt
    • @property 字符串 $email
    • @property 字符串 $activation_code
    • @property 字符串 $forgotten_password_code
    • @property 字符串 $remember_code
    • @property 整数 $last_login
    • @property 整数 $active
    • @property 整数 $groups_id
    • @property 组 $Groups
      • @package ##PACKAGE##
    • @subpackage ##SUBPACKAGE##
    • @author ##NAME##
    • @version SVN: $Id: Builder.php 6401 2009-09-24 16:12:04Z guilhermeblanco $ */
 abstract class BaseUsers extends Doctrine_Record
 {
     public function setTableDefinition()
     {
    $this->actAs("Timestampable");
    $this->setTableName('users');
    $this->hasColumn('id', 'integer', 4, array(
         'type' => 'integer',
         'length' => 4,
         'unsigned' => 0,
         'primary' => true,
         'autoincrement' => true,
         ));
    $this->hasColumn('username', 'string', 45, array(
         'type' => 'string',
         'length' => 45,
         'fixed' => false,
         'primary' => false,
         'notnull' => false,
         'autoincrement' => false,
         ));
    $this->hasColumn('password', 'string', 45, array(
         'type' => 'string',
         'length' => 45,
         'fixed' => false,
         'primary' => false,
         'notnull' => false,
         'autoincrement' => false,
         ));
    $this->hasColumn('ip_address', 'string', 16, array(
         'type' => 'string',
         'length' => 16,
         'fixed' => true,
         'primary' => false,
         'notnull' => false,
         'autoincrement' => false,
         ));
    $this->hasColumn('created_at', 'date', null, array(
         'type' => 'date',
         'primary' => false,
         'notnull' => true,
         'autoincrement' => false,
         ));
    $this->hasColumn('updated_at', 'date', null, array(
         'type' => 'date',
         'primary' => false,
         'notnull' => true,
         'autoincrement' => false,
         ));
    $this->hasColumn('salt', 'string', 40, array(
         'type' => 'string',
         'length' => 40,
         'fixed' => false,
         'primary' => false,
         'notnull' => false,
         'autoincrement' => false,
         ));
    $this->hasColumn('email', 'string', 40, array(
         'type' => 'string',
         'length' => 40,
         'fixed' => false,
         'primary' => false,
         'notnull' => false,
         'autoincrement' => false,
         ));
    $this->hasColumn('activation_code', 'string', 40, array(
         'type' => 'string',
         'length' => 40,
         'fixed' => false,
         'primary' => false,
         'notnull' => false,
         'autoincrement' => false,
         ));
    $this->hasColumn('forgotten_password_code', 'string', 40, array(
         'type' => 'string',
         'length' => 40,
         'fixed' => false,
         'primary' => false,
         'notnull' => false,
         'autoincrement' => false,
         ));
    $this->hasColumn('remember_code', 'string', 40, array(
         'type' => 'string',
         'length' => 40,
         'fixed' => false,
         'primary' => false,
         'notnull' => false,
         'autoincrement' => false,
         ));
    $this->hasColumn('last_login', 'integer', 4, array(
         'type' => 'integer',
         'length' => 4,
         'unsigned' => 1,
         'primary' => false,
         'notnull' => false,
         'autoincrement' => false,
         ));
    $this->hasColumn('active', 'integer', 1, array(
         'type' => 'integer',
         'length' => 1,
         'unsigned' => 1,
         'primary' => false,
         'notnull' => false,
         'autoincrement' => false,
         ));
    $this->hasColumn('groups_id', 'integer', 4, array(
         'type' => 'integer',
         'length' => 4,
         'unsigned' => 1,
         'primary' => true,
         'autoincrement' => false,
         ));
}

public function setUp()
{
    parent::setUp();
$this->hasOne('Groups', array(
         'local' => 'groups_id',
         'foreign' => 'id'));
$this->hasOne('Profile', array(
        'local' => 'id',
        'foreign' => 'users_id'));
}
 }

 <?php

/** * 基本配置文件 * * 这个类是由 Doctrine ORM 框架自动生成的 * * @property 整数 $id * @property 字符串 $role * @property 字符串 $first * @property 字符串 $last * @property 字符串 $email * @property 字符串 $phone_1 * @property 字符串 $phone_2 * @property 字符串 $address * @property 字符串 $postcode * @property 日期 $created_at * @属性日期 $updated_at * @property Doctrine_Collection $Member * @property Doctrine_Collection $Post * @property Doctrine_Collection $ThreadHasProfile * @property Doctrine_Collection $UserSetting * * @package ##PACKAGE## * @subpackage ##SUBPACKAGE## * @author ##NAME## * @version SVN: $Id: Builder.php 6401 2009-09-24 16:12:04Z guilhermeblanco $ */ 抽象类 BaseProfile 扩展 Doctrine_Record { 公共函数 setTableDefinition() { $this->actAs("时间戳"); $this->setTableName('profile'); $this->hasColumn('id', 'integer', 4, array( '类型' => '整数', '长度' => 4, '无符号' => 0, '主要' => 真, '自动增量' => 真, )); $this->hasColumn('users_id', 'integer', 4, array( '类型' => '整数', '长度' => 4, '无符号' => 0, '主要' => 假, '自动增量' => 假, )); $this->hasColumn('role', 'string', null, array( '类型' => '字符串', '固定' => 假, '主要' => 假, 'notnull' => 真, '自动增量' => 假, )); $this->hasColumn('first', 'string', 45, array( '类型' => '字符串', '长度' => 45, '固定' => 假, '主要' => 假, 'notnull' => 真, '自动增量' => 假, )); $this->hasColumn('last', 'string', 45, array( '类型' => '字符串', '长度' => 45, '固定' => 假, '主要' => 假, 'notnull' => 真, '自动增量' => 假, )); $this->hasColumn('phone_1', 'string', 45, array( '类型' => '字符串', '长度' => 45, '固定' => 假, '主要' => 假, 'notnull' => 假, '自动增量' => 假, )); $this->hasColumn('phone_2', 'string', 45, array( '类型' => '字符串', '长度' => 45, '固定' => 假, '主要' => 假, 'notnull' => 假, '自动增量' => 假, )); $this->hasColumn('address', 'string', 200, array( '类型' => '字符串', '长度' => 200, '固定' => 假, '主要' => 假, 'notnull' => 假, '自动增量' => 假, )); $this->hasColumn('postcode', 'string', 10, array( '类型' => '字符串', '长度' => 10, '固定' => 假, '主要' => 假, 'notnull' => 假, '自动增量' => 假, )); $this->hasColumn('created_at', 'date', null, array( '类型' => '日期', '主要' => 假, 'notnull' => 真, '自动增量' => 假, )); $this->hasColumn('updated_at', 'date', null, array( '类型' => '日期', '主要' => 假, 'notnull' => 真, '自动增量' => 假, )); }

public function setUp()
{
    parent::setUp();
$this->hasMany('Member', array(
         'local' => 'id',
         'foreign' => 'profile_id'));

    $this->hasMany('Post', array(
         'local' => 'id',
         'foreign' => 'profile_id'));

    $this->hasMany('ThreadHasProfile', array(
         'local' => 'id',
         'foreign' => 'profile_id'));

    $this->hasMany('UserSetting', array(
         'local' => 'id',
         'foreign' => 'profile_id'));

    $this->hasOne('Users', array(
        'local' => 'users_id',
        'foreign' => 'id'));
}

}

【问题讨论】:

  • 您能否提供您的学说模型(PHP 或 YAML 格式)以帮助回答问题

标签: doctrine models foreign-key-relationship


【解决方案1】:

有很多方法可以给这只猫剥皮。我根据从您的问题中收集到的内容大致创建了一个简化示例。

首先,这是我用来为我的一对一模型类生成的 YAML:

Identity:
  columns:
    username: string(50)
    password: string(50)
    email: string(50)

Profile:
  columns:
    identity_id: integer(10)
    firstname: string(50)
    lastname: string(50)
  relations:
    Identity:
      foreignType: one

现在在 PHP 中,我可以创建一个新的身份(或在您的情况下为用户)并添加相关的个人资料数据,只需:

        $identity = new Identity();
        $identity->username = 'james';
        $identity->password = 'secret';
        $identity->email = 'james@bond.com';
        //now adding the related data
        $identity->Profile->firstname = 'james';
        $identity->Profile->lastname = 'bond';
        $identity->save();

希望这个例子对你有所帮助。

编辑:

以下是从 YAML 生成的类,以防万一:

BaseIdentity.php

<?php
abstract class BaseIdentity extends Doctrine_Record
{
    public function setTableDefinition()
    {
        $this->setTableName('identity');
        $this->hasColumn('username', 'string', 50, array(
             'type' => 'string',
             'length' => '50',
             ));
        $this->hasColumn('password', 'string', 50, array(
             'type' => 'string',
             'length' => '50',
             ));
        $this->hasColumn('email', 'string', 50, array(
             'type' => 'string',
             'length' => '50',
             ));
    }

    public function setUp()
    {
        parent::setUp();
        $this->hasOne('Profile', array(
             'local' => 'id',
             'foreign' => 'identity_id'));
    }
}

BaseProfile.php

<?php

abstract class BaseProfile extends Doctrine_Record
{
    public function setTableDefinition()
    {
        $this->setTableName('profile');
        $this->hasColumn('identity_id', 'integer', 10, array(
             'type' => 'integer',
             'length' => '10',
             ));
        $this->hasColumn('firstname', 'string', 50, array(
             'type' => 'string',
             'length' => '50',
             ));
        $this->hasColumn('lastname', 'string', 50, array(
             'type' => 'string',
             'length' => '50',
             ));
    }

    public function setUp()
    {
        parent::setUp();
        $this->hasOne('Identity', array(
             'local' => 'identity_id',
             'foreign' => 'id'));
    }
}

【讨论】:

  • 应该的。我将不得不仔细阅读您的代码,看看还会发生什么。你能为你的模型弹出 YAML 吗? - 它比实际的 PHP 生成的类更容易处理
  • 我去试试!我以前从未生成过 YAML 文件。有没有简单的方法来做到这一点?另外,我现在不在电脑旁,所以可能会有延迟!
  • 我在尝试使用 Doctrine 将我的模型转换为 yaml 时遇到权限问题。我假设 Doctrine 将尝试将新文件保存在网络根目录中,所以我不明白为什么不允许这样做!
【解决方案2】:

$p-&gt;save(); 之前,有$p-&gt;users_id = $u-&gt;id

另外,你为什么称表 Users(复数)?这只会让代码变得非常混乱。

同样,如果您有单独的表来保存有关用户的不同信息(用户和用户的个人资料),因为您在 sfGuardPlugin 中看到了它,请不要这样做!这是一个荒谬的想法,只会让你以后后悔。我不知道 Symfony/Doctrine 团队在想到这个想法时在喝什么……

【讨论】:

  • 有点工作...错误消失了,但配置文件表中的 users_id 列的值为 0 而不是 users.id 的值。至于您的其他建议,代码实际上是基于 ion_auth 库的 codeigniter。该表被称为 users 因为我没有时间更改它。我已将数据分离出来,以将身份验证所需的数据与用户的一般数据分开。
  • 将配置文件存储在单独的表中不只是基本的数据库规范化吗?为什么很可笑?
猜你喜欢
  • 1970-01-01
  • 2015-09-22
  • 2018-08-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多