Love Fuel?    Donate

FuelPHP Forums

Ask your question about FuelPHP in the appropriate forum, or help others by answering their questions.
DRY method of defining model columns and using UUIDs instead of auto_increment IDs
  • Hi,

    I've used cakePHP in the past and am exploring fuelPHP now. I'm still a noob so please excuse any dumb questions. I did a search on this but didn't find anything yet. 

    Question 1: Is there a DRY way to define columns for models? 

    I have status flags SOME of my tables in my database. Status of type tinyint(1) can hold a 1 or 0. I find myself defining status over and over again in my fuel model classes. I'm wondering if there is DRY way of handling this or if there is a design decision behind not handling this. 

    My initial idea was to extend the Orm w/ my own custom MyOrm and define it in the _properties member where i can set the default to 1. 

    Question 2: Can I use UUIDs for ID instead of autoincrement ID? 
    My database uses UUIDs (format like 5047b029-a7e0-4c57-83d4-493c77bd6c23) instead of auto-increment integers as IDs (like 1, 2, 3, etc). 

    I have created my own MyOrm class which extends  Orm and overwritten the __construct method to do this:

    public function __construct(array $data = array(), $new = true, $view = null)
    {
    // clipped
    if ($new)
    {
    $properties = $this->properties();
    foreach ($properties as $prop => $settings)
    {
    if (array_key_exists($prop, $data))
    {
    $this->_data[$prop] = $data[$prop];
    }
    elseif (array_key_exists('default', $settings))
    {
    $this->_data[$prop] = $settings['default'];
    }
    /* my code start */
    elseif ($prop === 'id') 
    {
    $this->_data['id'] = Utility::uuid();
    }
    /* my code end */
    }
    }
    // clipped
    }

    Is there a better way to do this? 

    Thanks
  • HarroHarro
    Accepted Answer
    I do exactly the same. I have an application where each table has a create, an update and a userid field. I just created a base model that extends Orm\Model, which defines these properties, and the observers needed to make them work.

    The Models themselfs then extend the base model.

    As to the UUID, I would use the same base model to extend the insert method, assign the UUID to $this->id if null, and call the parent method to insert the record. Much cleaner then doing it in the constructor, because the ORM expects an object in state 'new' not to have a PK.
  • What is best method for extending a base models properties in a mixin type manner?  Looking to do this same scenario, have id/created_at/updated_at/created_by/updated_by/assigned_to/deleted as "base" properties.

    In working prototype I created a base model extending Orm, then all other models extend base.  I extend the __construct method to merge the properties and observers between parent/child:

        public function __construct(array $data = array(), $new = true, $view = null)
        {
            $class = get_class($this);
            $child_properties = $class::$_properties;
            $base_properties = self::$_properties;
            $class::$_properties = array_merge($base_properties, $child_properties);

            if($class::$_observers)
            {
                $child_observers = $class::$_observers;
                $base_observers = self::$_observers;
                $class::$_observers = array_merge($base_observers,$child_observers);
            }
            parent::__construct($data, $new, $view);
        }

    Seems like easiest way since the properties seem to be set and cached right away in the Orm model constructor.
  • All these properties are static, so do it in _init(), not in __construct(). It only needs to happen once, when the class is loaded.

    This is how I do it.

    Also, you'll have to make it a bit more foolproof, the extended class can define it's own properties and observers, array_merge() might overwrite existing definitions.
  • With using _init() how do you reference the child classes static properties to merge in?  In the __construct I can do get_class($this) in order to access, but with the static _init() $this doesnt exist, tried get_called_class() but was getting some weird errors.  What is method for getting the child class from within the static _init() call?

    On the second note regarding array_merge() usage, my intended behavior is to have the extension be additive or destructive with the model the child is extending and loading over, so no worries on overwriting.
  • You don't need the classname, you're in the class. So you can just use static (as in 'static::$properties') to access the class properties.

    I do exactly the same as you want here, and that works fine.

Howdy, Stranger!

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

In this Discussion