1

I have tried to create one-to-many connection, but it works very strange.

I suspect that class User has one Country, and class Country has many Users. But User->Country return ever an array with one Country, (Doctrine Collection, not a Record).

Have anyone idea why?

  • I need CountryUser object, and I know, that such relation can be made without additional object.
  • I'm not using YAML format for Doctrine, classes are made manualy.

    class User extends sfDoctrineRecord {

    public function setTableDefinition()
    {
        $this->setTableName('user');
        $this->hasColumn('id', 'integer', 5, array(
             'type' => 'integer',
             'primary' => true,
             'unsigned' => true,
             'autoincrement' => true,
             'length' => 5,
             ));
        $this->hasColumn('fbid', 'string', 40, array(
             'type' => 'string',
             'length' => 40,
             #'notnull' => true,
             #'unique' => true,
             ));
    }
    
    public function setUp()
    {
        parent::setUp();
        $this->hasOne('Country', array(
             'local' => 'user_id',
             'foreign' => 'country_id',
             'refClass' => 'CountryUser'
        ));
    
        $timestampable0 = new Doctrine_Template_Timestampable(array(
             ));
        $this->actAs($timestampable0);
    }
    

    }

    class Country extends sfDoctrineRecord { public function setTableDefinition() { $this->setTableName('country');

        $this->hasColumn('id', 'integer', 5, array(
             'type' => 'integer',
             'primary' => true,
             'unsigned' => true,
             'autoincrement' => true,
             'length' => 5,
             ));
    
        $this->hasColumn('name', 'string', 10, array(
          'type' => 'string',
          'length' => 10,
          'unique' => true,
          #'notnull' => true,
        ));
    }
    
    public function setUp()
    {
        parent::setUp();
    
        $this->hasMany('User as Users', array(
             'local' => 'country_id',
             'foreign' => 'user_id',
             'refClass' => 'CountryUser'
         ));
    
        $timestampable0 = new Doctrine_Template_Timestampable(array(
             ));
        $this->actAs($timestampable0);
    }
    

    }

    class CountryUser extends sfDoctrineRecord {

    public function setTableDefinition() {

    $this->setTableName('country_user');
    
    $this->hasColumn('user_id', 'integer', 5, array(
      'notnull' => true,
      'unsigned' => true,
      'length' => 5,
      'type' => 'integer',
      'primary' => true,
    ));
    
    $this->hasColumn('country_id', 'integer', 5, array(
      'type' => 'integer',
      'notnull' => true,
      'unsigned' => true,
      'length' => 5,
      'primary' => true,
    ));
    

    } }

burgua
  • 90
  • 6

1 Answers1

1

I need CountryUser object, and I know, that such relation can be made without additional object.

But that is the answer to your question. Youre setting it up as a many-to-many by using the refClass as such youre always goign to get a Doctrine_Collection when accessing the relation. This is how it works, im not sure why you would expect a single object.

You might be able to override the accessor to only return a single record if there is only one in the collection, but this is most likely going to break things because everything is going to be expecting a Doctine_Collection to be returned from this accessor:

class User extends sfDoctrineRecord {
    public function getCountry(
       $coll = $this->_get('Country');
        if($coll->count() == 1){
          return $coll->getFirst();
        }
        else
        {
          return $coll;
        }
    }
}

The real solution is to use the proper type of relationship...

Also... if youre using Symfony why in gods name are you not using the YAML definitions? Its so much easier to use and manage.

prodigitalson
  • 60,050
  • 10
  • 100
  • 114
  • Hm, I had the same problem with YAML. But, thx prodigitalson, now I know, that refClass forces many-to-many. I just have really lot of relations in project. And they change very fast (add new, make new structure). That's why it was a good idea, to make separate Tables for pure Models-Tables and Relations-Tables. To have in object also a lot of keys was not great for me. And such hack in Model is only one way? (( – burgua Jan 16 '11 at 22:40
  • @burgua: Yes, YAML wont make a difference here. This is the way Dcotrine works regardless of how your models are constructed. Im not suer why you need to have a separate table for relations that arent m2m, regardless of how fast your schema changes. You need to be correcting the classes when that happens... IF you use the yaml then that as simple as executing a few tasks and maybe customizing a generated migration if you need to keep db data intact, on the other hand if youre doing things manually thats a headache - but using `refClass` is not a solution :-) – prodigitalson Jan 16 '11 at 22:45
  • @burgua: Or are you talking about implementing an EAV Model with Doctrine? – prodigitalson Jan 16 '11 at 22:49
  • hm, thx. I know, that it's headache. Now will rewrite my old YAML proper for one-to-many relations. And I will read more about migrations. I hope. It will help me further ( – burgua Jan 16 '11 at 22:50
  • no, dunno about EAV, but if it's for "dynamical attributes", I dont need it. Thx anyway – burgua Jan 17 '11 at 00:01