Question

I'll use an abstract (and simple) example to illustrate the question: CarDomainObject, as follows: (example mysql data types are listed beside the members)

class carDomainObject extends DomainObjectAbstract {

    public $uid;                //int
    public $make;               //varchar
    public $model;              //varchar
    public $productionDate;     //timestamp
    public $doors;              //tinyint

}

class DomainObjectAbstract {

    public function setData(array $data=array())
    {
        foreach ($data as $key => $value)
        {
            if ( ! empty($key))
            {
               $this->$key = $value;
            }
        }
    }

    //if $val is not passed, checks for ANY set value,
    //  else checks that $this->$val is set (dirty)
    public function isDirty($val=false)
    {
        foreach(get_object_vars($this) as $key => $property)
        {
            if( ! is_null($property) && ( ! $val || $key == $val))
            {
                return true;
            }
        }
        return false;
    }

}

Say that we want to insert a new car into the database, so we set some values:

$carDomainObject->setData(array('make' => 'ford', 'model' => 'taurus'));

Now the values that aren't set will still be NULL, which works well for the isDirty() method. What this schema doesn't work for is when inserting an object (that's been initialized like above, with only certain values) into the database, where NULL might not be a valid value for the column.

So, my question is: How can we validate that each of the data pieces within the domain object is ready for DB insertion? The way I see it there's a few options:

  1. If we use default values for the member variables (0 for an int, '' for a varchar, etc), then isDirty() becomes more complex, because a null check wouldn't be sufficient. However, checking that the data is able to be inserted becomes trivial because the default values could be inserted without issue

  2. If we stick with NULL as the default values, then isDirty() stays fairly trivial, but ensuring the data is ready for the DB becomes complex.

  3. Validate each variable individually, which would get ugly very quickly depending on the DO.

  4. Use default values within MySQL - Not really an option for me, but a valid option in general

Was it helpful?

Solution

I get a feeling that you took parts of this post, but misunderstood the problem, that was solved there.

You seem to be trying to determine, if model is valid, before it gets saved. But your structure is flawed:

  1. If you using single setter, then this setter will grow in complexity as you try to add more and more conditions. Also, by avoiding separate setter for each parameter, you loose the ability to actually validate the parameters.

    When you set invalid value to domain object, it should create internal error state.

  2. Your validation assumes, that all values must be not-null. What if they can be NULL? Validation of parameters should check, if values confirm with business rules, not with constraints set by database.

  3. When mapper tries to store invalid values in the database, it will cause an error. If you are using properly set up PDO instance, it will rise an exception. How you handle that exception, then is your choice. Domain objects are not responsible for data integrity in database.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top