CodeIgniter Forums
DataMapper ORM v1.8.0 - Printable Version

+- CodeIgniter Forums (https://forum.codeigniter.com)
+-- Forum: Archived Discussions (https://forum.codeigniter.com/forumdisplay.php?fid=20)
+--- Forum: Archived Libraries & Helpers (https://forum.codeigniter.com/forumdisplay.php?fid=22)
+--- Thread: DataMapper ORM v1.8.0 (/showthread.php?tid=37531)



DataMapper ORM v1.8.0 - El Forum - 03-11-2011

[eluser]Burton Kent[/eluser]
I'm not sure if this would be considered a bug, but if you use $object->skip_validation(); then later try to validate the field, unchanged fields will skip validation.

So for example, suppose I have a list of users, and I don't have their complete information. I might insert them with the intention of the users later updating their information. The way things work now, validation couldn't be used to force them to make updates.

This is caused by code at about line 2143 in datamapper.php:

Code:
// Check if property has changed since validate last ran
      if ($related || ! isset($this->stored->{$field}) || $this->{$field} !== $t
his->stored->{$field})

The fix is simple - a flag, a method to set the flag, and a check for the flag.

The flag - At about line 407, insert two lines after the protect $_validated declaration:
Code:
// tracks whether or not the object has already been validated
  protected $_validated = FALSE;
  // forces validation on items that haven't changed
  protected $_force_revalidation = FALSE;

Method to set the flag - At about line 2269 (after the skip_validation() declaration) insert:
Code:
// --------------------------------------------------------------------

  /**
   * Skips validation for the next call to save.
   * Note that this also prevents the validation routine from running until the
next get.
   *
   * @param object $skip If FALSE, re-enables validation.
   * @return  DataMapper Returns self for method chaining.
   */
  public function force_revalidation($force = TRUE)
  {
    $this->_force_revalidation = $force;
    return $this;
  }

Check for the flag - Add one small test to the end of about line 2143 as noted above:
Code:
// Check if property has changed since validate last ran
      if ($related || ! isset($this->stored->{$field}) || $this->{$field} !== $t
his->stored->{$field} || $this->_force_revalidation)

Then to force re-validation just use $object->force_revalidation(); before any $object->save();

This was hard to find because validation worked perfectly for normal or new entries. When I imported data to work with, validation started failing for no apparent reason.


DataMapper ORM v1.8.0 - El Forum - 03-11-2011

[eluser]WanWizard[/eluser]
skip_validation() is only valid until the first save() or get(), after which it will be reset.

If you need to reset it earlier, just call skip_validation(FALSE) to re-enable validation.


DataMapper ORM v1.8.0 - El Forum - 03-11-2011

[eluser]Burton Kent[/eluser]
[quote author="WanWizard" date="1299882704"]skip_validation() is only valid until the first save() or get(), after which it will be reset.

If you need to reset it earlier, just call skip_validation(FALSE) to re-enable validation.[/quote]

skip_validation() sets $this->_validated, which is checked at the very beginning of validate().

This line comes after anything affected by skip_validation() - skip_validation() won't help here:

Code:
// Check if property has changed since validate last ran
      if ($related || ! isset($this->stored->{$field}) || $this->{$field} !== $t
his->stored->{$field})



DataMapper ORM v1.8.0 - El Forum - 03-11-2011

[eluser]WanWizard[/eluser]
Ok, understood. I'll add it to the list for v1.8.1.


DataMapper ORM v1.8.0 - El Forum - 03-12-2011

[eluser]cavijayan[/eluser]
I have a question :

I'm using Ion Auth library to authenticate my users. In the Meta table, i store the user relationship to manager_id, which is self reference to another user.

Manager has many employees.
Employee has only one Manager.

My Table Details:

Users
Code:
CREATE TABLE IF NOT EXISTS `users` (
  `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
  `group_id` mediumint(8) unsigned NOT NULL,
  `ip_address` char(16) NOT NULL,
  `username` varchar(15) NOT NULL,
  `password` varchar(40) NOT NULL,
  `salt` varchar(40) DEFAULT NULL,
  `email` varchar(100) NOT NULL,
  `activation_code` varchar(40) DEFAULT NULL,
  `forgotten_password_code` varchar(40) DEFAULT NULL,
  `remember_code` varchar(40) DEFAULT NULL,
  `created_on` int(11) unsigned NOT NULL,
  `last_login` int(11) unsigned DEFAULT NULL,
  `active` tinyint(1) unsigned DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM;

Meta
Code:
CREATE TABLE IF NOT EXISTS `meta` (
  `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
  `user_id` mediumint(8) unsigned DEFAULT NULL,
  `name` varchar(50) DEFAULT NULL,
  `nric` varchar(9) DEFAULT NULL,
  `gender` varchar(6) DEFAULT NULL,
  `phone` varchar(8) DEFAULT NULL,
  `deptartment_id` int(3) DEFAULT NULL,
  `position_id` int(3) DEFAULT NULL,
  `supervisor_id` int(11) DEFAULT NULL,
  `manager_id` int(11) DEFAULT NULL,
  `date_joined` date DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM ;

So i define the Datamapper Model as follows:

Code:
<?php

class User extends DataMapper {
    
    var $has_one = array("meta");
    
    // Optionally, don't include a constructor if you don't need one.
    function __construct($id = NULL)
    {
        parent::__construct($id);
    }

    // Optionally, you can add post model initialisation code
    function post_model_init($from_cache = FALSE)
    {
    }
}

/* End of file user.php */
/* Location: ./application/models/user.php */

For the meta model which stores the other details of employees

Code:
<?php

class Meta extends DataMapper {
    var $table = "meta";
    var $has_one = array('manager' => array(
                    'class' => 'meta',
                    'other_field' => 'manager_id'
                    ),"user","position","department");
    
    // Optionally, don't include a constructor if you don't need one.
    function __construct($id = NULL)
    {
        parent::__construct($id);
    }

    // Optionally, you can add post model initialisation code
    function post_model_init($from_cache = FALSE)
    {
    }
}

/* End of file meta.php */
/* Location: ./application/models/meta.php */

My question is :

Am I doing the self-relationship correctly in the model ?

If not, Can someone please help in defining it ?

Thank you so much.


DataMapper ORM v1.8.0 - El Forum - 03-13-2011

[eluser]WanWizard[/eluser]
Other field should be "manager", Datamapper will append "_id" to it.


DataMapper ORM v1.8.0 - El Forum - 03-14-2011

[eluser]IgnitedCoder[/eluser]
@WanWizard,

First thanks for your help as always...

I have 2 objects that are exactly the same...

my_wallposts and friend_wallposts

I need to create a union between these two and sort them by date/time.

Is this possible?

Regards,
Brendan


DataMapper ORM v1.8.0 - El Forum - 03-15-2011

[eluser]WanWizard[/eluser]
Datamapper does relationships, to execute a union between two unrelated tables is not part of the functionality.

Either use a standard AR query, or retrieve both separately, create an array with the contents of both $object->all array's, and sort them in PHP.
If you use the date/time (with an id suffix to make sure it's unique) as the array key, and assign the all objects by reference, sorting will we quick and will not use extra memory.


DataMapper ORM v1.8.0 - El Forum - 03-17-2011

[eluser]Madmartigan1[/eluser]
Hey WanWizard,

Just wanted to say thanks for maintaining this amazing library.
After kerplunking it into my CMS, I've been having a great time converting the whole thing to use Datamapper.
Really awesome work. I've been using a custom Model class extension for the past couple years, and finally reached the point where things were getting unmaintainable. Datamapper cleaned that all up. The docs are very well written and the examples are very helpful.

Thanks again,
-Madmartigan


DataMapper ORM v1.8.0 - El Forum - 03-18-2011

[eluser]WanWizard[/eluser]
@Madmartigan1,

Thanks for the kudos. Feedback like this makes me forget all the long nights I've worked on it... Smile

(and don't forget all the work my predecessors have spend on it as well. Thanks go to them too!)