Welcome Guest, Not a member yet? Register   Sign In
Help with My_Model and extending it?
#1

Hi,

Been playing around with Jamie rumbelow's My_Model and find it really useful so far.

Just working with the 'observers' before_create and before_update. I've only been testing these observers with one model so far.

In that model I've got the following code:

PHP Code:
public $before_update = array( 'timestamps_for_update' );
 public 
$before_create = array( 'timestamps_for_create' );
 
 
   protected function timestamps_for_update($data)
 
   {
 
$data['updated_at'] = date('Y-m-d H:i:s');
 
$data['updated_by'] = $this->session->userdata('username'); 
 return 
$data;
 
   
 
    
    protected 
function timestamps_for_create($data)
 
   {
 
$data['created_at'] = $data['updated_at'] = date('Y-m-d H:i:s');
 
$data['created_by'] = $data['updated_by'] = $this->session->userdata('username'); 
 return 
$data;
 
   

Now, if I want to extend this functionality to all models in my app I don't want to write this code in every one ... so what's the best way tp proceed with this - use a 'Base' model to extend MY_Model and put the code in there and then extend all models from that?

Or is there another, better way?
Reply
#2

(This post was last modified: 04-22-2015, 11:30 PM by Avenirer. Edit Reason: Added a post-scriptum )

You can at any time put that function inside the MY_Model and in the constructor of MY_model to append the function to those arrays.

PS: You can also try my MY_Model: https://github.com/avenirer/CodeIgniter-MY_Model
Reply
#3

Thanks for replying.

Your answer makes sense to me ... what is the main difference between your MY_Model and JR's version?
Reply
#4

(This post was last modified: 04-23-2015, 03:55 AM by Avenirer.)

Well... mine is a copy of JR's, is newer, and has more bugs in it Smile But actually I hoped that if enough people will use it, the bugs will slowly disappear from it.

...Also, it does the created_at, updated_at, and deleted_at automatically if asked for... Big Grin
Reply
#5

Nice answer, I like the honesty Smile

Just thinking though ...

to add the code into MY_Model constructor would automatically implement it for every model that extends it, wouldn't it?

... let's say I want to utilise the updating of 'created_at', 'updated_at' etc. fields for some models but not for others.

How would you go about implementing that?

Thanks.
Reply
#6

(04-23-2015, 04:33 AM)blackbulldog Wrote: Nice answer, I like the honesty Smile

Just thinking though ...

to add the code into MY_Model constructor would automatically implement it for every model that extends it, wouldn't it?

... let's say I want to utilise the updating of 'created_at', 'updated_at' etc. fields for some models but not for others.

How would you go about implementing that?

Thanks.

Are we talking about my MY_Model? Because if we are, you can make those settings in the constructor. If you are talking about JR's... then I guess you have a small problem...
Reply
#7

I was thinking about both ... I'll have to have a look and see which fits best.

thanks..
Reply
#8

A number of other models already implement similar functionality. For instance, Bonfire's BF_Model does a few things to implement this:
  • Add a series of properties to control the name of these fields, when included
  • Add a series of properties to control whether these fields are included
  • Add a property to control the format of the date fields
So, the properties look something like this:

PHP Code:
   protected $created_field 'created_on';
 
   protected $modified_field 'modified_on';
 
   protected $deleted_field 'deleted';

 
   protected $set_created false;
 
   protected $set_modified false;
    protected $soft_deletes false;
 
   protected $log_user false;

 
   protected $created_by_field 'created_by';
 
   protected $modified_by_field 'modified_by';
 
   protected $deleted_by_field 'deleted_by';

 
   protected $date_format 'datetime'

Note that, in this case, I've defaulted the set_created, set_modified, soft_deletes, and log_user properties to false, which would be ideal if you were adding this to a base model which is already being used by your models, since it would leave the existing models unchanged until you changed the values of those properties in each model. If you wanted one or more of those features supported by default, you would just set the property to true in the base model.

The base model's constructor then checks the properties and sets the relevant observers:

PHP Code:
       if ($this->set_created === true) {
 
           array_unshift($this->before_insert'created_on');
 
       }
 
       if ($this->set_modified === true) {
 
           array_unshift($this->before_update'modified_on');
 
       

(Note: Bonfire only supports created_by and modified_by if created_on and modified_on are also set, and the feature is controlled by the $log_user property. Supporting them independently would require additional variables and observers.)

Then the created_on observer looks something like this (modified_on is very similar):

PHP Code:
   public function created_on($row)
 
   {
 
       if (! array_key_exists($this->created_field$row)) {
 
           $row[$this->created_field] = $this->set_date();
 
       }

 
       return $row;
 
   

Notice that the field name in the row is retrieved from $this->created_field and the date is set by calling $this->set_date(), which looks something like this:


PHP Code:
   protected function set_date($user_date null)
 
   {
 
       $curr_date = empty($user_date) ? time() : $user_date;
 
       $dateFormat '';

 
       switch ($this->date_format) {
 
           case 'datetime':
 
               $dateFormat 'Y-m-d H:i:s';
 
               break;
 
           case 'date':
 
               $dateFormat 'Y-m-d';
 
               break;
 
           case 'int':
 
               // no break;
 
           default:
 
               $dateFormat 'U';
 
               break;
 
       }

 
       return (strtolower($this->config->item('time_reference')) == 'gmt' ?
 
               gmdate($dateFormat$curr_date) :
 
               date($dateFormat$curr_date));
 
   

This allows the model to control the format of the date fields (in $this->date_format), though it would have to be modified if you needed to support multiple formats within a single model. (A method is supplied to change the format at runtime, though.)

Some of the code in BF_Model predates the inclusion of the observers, so some of the features are not implemented as cleanly as possible, but it does give an idea of how to abstract certain elements of the code (such as field names, date types, and whether the features are enabled). These tend to be the types of things that are easily overlooked until you've worked through the implementation a few times.
Reply




Theme © iAndrew 2016 - Forum software by © MyBB