Love Fuel?    Donate

FuelPHP Forums

Ask your question about FuelPHP in the appropriate forum, or help others by answering their questions.
CRUD Object Strangeness
  • I have created a model extending the Model_Crud. I have defined the _table_name, _primary_key and _properties for the model. I have overridden the save() method so that I can add a primary key to the model before it is saved for the first time. The primary key is a random md5 string (it will be a UUID, but just using md5 for testing).
        public function save()
        {
            if ($this->is_new()) {
                $this->table_id = md5(rand(1,1000000));
            }
    
            parent::save();
        }
    

    Now the problem I am having is that creating a model instance then issuing save() on it does create a row in the database with a random primary key. However, the key is then not available to the saved object, and the object still returns TRUE for a call to is_new(). So issuing save() on the object three times will create three rows in the database, and not just one (with two updates). I am either doing something very dumb and probably obvious, or this is perhaps the wrong place to set the primary key? Perhaps the pre_save() method is the place to do it? -- Jason
  • Another piece of the puzzle: after doing a $model->save(), the value of $model->table_id (the primary key) is zero (0). The primary key is defined as a varchar in the database and in the model, so I'm not sure where a zero is coming from. Does the CRUD model perhaps assume that the primary key will be a numeric column? What I want to be able to do, is create the model object, set a few properties, save it, then take the primary key that is generated as a part of the save process to use in further processes. I'm using 1.1 RC1, so perhaps there are additions in git that I need to pull in?
  • Getting closer: I realise the primary key I am setting is being over-ridden with a string "0" on line 357 of the Model_Crud:
    $result = $query->execute(isset(static::$_connection) ? static::$_connection : null);
    $result[1] > 0 and $this->set($vars); // Move the values set into the object, including the PK
    $this->{static::primary_key()} = $result[0]; // <<-- here, overwrite the PK with "0"
    

    So the problem is in the query model, or perhaps the query model is not being told by the CRUD model which property is the primary key.
  • Yes, that is the problem. When inserting a model object into MySQL, the primary key of the object is set to the result of mysql_insert_id() without any question. This means all primary keys MUST be auto increment columns. The documentation hints that there is much more control over what can be used for primary keys. There is a related issue in the same bit of code (the save() method of the Model_Crus class) - the object "_is_new" properly needs to be reset to FALSE on a successful save. For the main fix, in the Model_Crud save() method, it may be sufficient to check whether the primary key is already set, and if it is, do *not* overwrite it. [Edit: raised this one as a bug https://github.com/fuel/core/issues/665] So the question is, is this a bug, or are auto_increment integers to be the *only* supported primary key for MySQL databases? There are times when I don't want to use a numeric primary key, and times when pointing at legacy systems for which there is no choice about the primary key (SugarCRM, for example, uses UUID for all keys, giving the ability to merge databases together relatively easily). -- Jason Of course - this stuff is probably already dealt with in the dev repository - I'll check.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion