Доктрина отношений - PullRequest
       24

Доктрина отношений

0 голосов
/ 04 сентября 2010

У меня есть две таблицы. Таблица пользователей и таблица профилей. Таблица профиля имеет внешний ключ 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

Если я просто сохраню данные в таблице пользователей, то я знаю, что это 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
    • @ свойство integer $ id
    • @ строка свойства $ username
    • @ строка свойства $ password
    • @ строка свойства $ ip_address
    • @ дата объекта $ созданная_
    • @ дата объекта $ updated_at
    • @ строка свойства $ salt
    • @ строка свойства $ email
    • @ строка свойства $ activ_code
    • @ строка свойства $ Forgotten_password_code
    • @ строка свойства $ запомнить_код
    • @ property integer $ last_login
    • @ property integer $ active
    • @ целое число свойства $ groups_id
    • @ property Группы $ Группы
      • @ package ## PACKAGE ##
    • @ subpackage ## SUBPACKAGE ##
    • @ author ## NAME ## <## EMAIL ##>
    • @ версия 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

/ ** * BaseProfile * * Этот класс был автоматически сгенерирован Doctrine ORM Framework * * @property integer $ id * @property string $ role * @property string $ first * @property string $ last * @property string $ email * @property строка $ phone_1 * строка @property $ phone_2 * @property строка $ адрес * @property строка $ почтовый индекс * @property date $ созданная_ат * @property date $ updated_at * @property Doctrine_Collection $ Member * @property Doctrine_Collection $ Post * @property Doctrine_Collection $ ThreadHasProfile * @property Doctrine_Collection $ UserSetting * * @package ## ПАКЕТ ## * @subpackage ## SUBPACKAGE ## * @author ## NAME ## <## EMAIL ##> * @version SVN: $ Id: Builder.php 6401 2009-09-24 16: 12: 04Z guilhermeblanco $ * / абстрактный класс BaseProfile расширяет Doctrine_Record { публичная функция setTableDefinition () { $ This-> ACTAS ( "Timestampable"); $ This-> setTableName ( 'профиль'); $ this-> hasColumn ('id', 'integer', 4, array ( 'type' => 'integer', 'длина' => 4, 'unsigned' => 0, 'primary' => true, 'autoincrement' => true, )); $ this-> hasColumn ('users_id', 'integer', 4, array ( 'type' => 'integer', 'длина' => 4, 'unsigned' => 0, 'primary' => false, 'autoincrement' => false, )); $ this-> hasColumn ('role', 'string', null, array ( 'type' => 'string', 'fixed' => false, 'primary' => false, 'notnull' => правда, 'autoincrement' => false, )); $ this-> hasColumn ('first', 'string', 45, array ( 'type' => 'string', 'длина' => 45, 'fixed' => false, 'primary' => false, 'notnull' => правда, 'autoincrement' => false, )); $ this-> hasColumn ('last', 'string', 45, array ( 'type' => 'string', 'длина' => 45, 'fixed' => false, 'primary' => false, 'notnull' => правда, 'autoincrement' => false, )); $ this-> hasColumn ('phone_1', 'string', 45, array ( 'type' => 'string','длина' => 45, 'fixed' => false, 'primary' => false, 'notnull' => ложь, 'autoincrement' => false, )); $ this-> hasColumn ('phone_2', 'string', 45, array ( 'type' => 'string', 'длина' => 45, 'fixed' => false, 'primary' => false, 'notnull' => ложь, 'autoincrement' => false, )); $ this-> hasColumn ('address', 'string', 200, array ( 'type' => 'string', 'длина' => 200, 'fixed' => false, 'primary' => false, 'notnull' => ложь, 'autoincrement' => false, )); $ this-> hasColumn ('почтовый индекс', 'строка', 10, массив ( 'type' => 'string', 'длина' => 10, 'fixed' => false, 'primary' => false, 'notnull' => ложь, 'autoincrement' => false, )); $ this-> hasColumn ('create_at', 'date', null, array ( 'type' => 'date', 'primary' => false, 'notnull' => правда, 'autoincrement' => false, )); $ this-> hasColumn ('updated_at', 'date', null, array ( 'type' => 'date', 'primary' => false, 'notnull' => правда, 'autoincrement' => false, )); }

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'));
}

}

Ответы [ 2 ]

1 голос
/ 04 сентября 2010

Есть несколько способов снять шкуру с этой кошки.Я создал упрощенный пример, основанный на том, что я могу почерпнуть из вашего вопроса.

Во-первых, вот 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();

Надеюсь, этот пример вам немного поможет.

edit:

Вот сгенерированные классы из 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'));
    }
}
0 голосов
/ 04 сентября 2010

До $p->save();, есть $p->users_id = $u->id.

Кроме того, почему вы называете таблицу User s (множественное число)? Это просто сделает код очень запутанным.

Также, опять же, если у вас есть отдельные таблицы для хранения различной информации о пользователе (пользователь и профиль пользователя), поскольку вы видели это в sfGuardPlugin, ПОЖАЛУЙСТА, НЕ ДЕЛАЙТЕ ЭТОГО! Это нелепая идея, которая заставит вас пожалеть об этом позже. Я не знаю, что пила команда Symfony / Doctrine, когда они думали об этой идее ...

...