MY_Model Abstract Class
MY_Model extends the Model class to provide common methods for retrieving and manipulating data from the database usually specific to a table.
It was developed to augment the CodeIgniter active record class and DOES NOT change any of those methods. The class is abstract, meaning that it needs to be extended to work.
MY_Model may require the following classes and helpers (depending on class preferences):
Table, Result and Record Classes
MY_Model is actually made up of 2-3 classes:
- Table Class - in charge of retrieving, validating and saving data to the data source
- Data Set Class - the result object returned by the table class after retrieving data (normally not directly used)
- Record Class (optional) - the custom object(s) returned by a retrieving query that contains at a minimum the column attibutes of the table
Initializing the Class
The MY_Model class is initialized in your controller using the $this->load->model function:
$this->load->model('examples_model');
Once loaded, the MY_Model object will be available using: $this->examples_model.
Configuring MY_Model Information
Public Properties
| Preference | Default Value | Options | Description |
|---|---|---|---|
| return_method | auto | object, array, query, auto | Return the results as either a query result, array or an object with the later being custom if there is a Data_record class assigned to the table |
| auto_validate | TRUE | TRUE/FALSE (boolean) | Automatically validate fields |
| auto_validate_fields | array( 'email|email_address' => 'valid_email', 'phone|phone_number' => 'valid_phone' ) |
None | Fields to auto validate |
| default_required_message | Please fill out the required field '%1s' | None | The default required message |
| auto_date_add | array('date_added', 'entry_date') |
None | Field names to automatically generate the datetime on insert |
| auto_date_update | array('last_modified', 'last_updated') |
None | Field names to automatically generate the datetime on update |
| date_use_gmt | FALSE | TRUE/FALSE (boolean) | Use GMT time |
| default_date | 0000-00-00 | None | The default date to be inserted |
| auto_trim | TRUE | TRUE/FALSE (boolean), string or an array of field names | Automatically trim the spaces from data values before inserting |
| auto_encode_entities | TRUE | TRUE/FALSE (boolean), string or an array of field names | Automatically encode HTML entities |
| xss_clean | TRUE | TRUE/FALSE (boolean), string or an array of field names | Automatically run the xss_clean function on fields |
| hidden_fields | None | None | Hidden fields that should appear by default when generating the models form |
| parsed_fields | None | None | Fields to automatically parse. |
| unique_fields | None | None | Fields that are not IDs but are unique. |
| linked_fields | None | None | Fields that are are linked. Key is the field, value is a function name to transform it. |
| foreign_keys | None | Array of column names with keys being the column and the value being the model. If the model exists in a specific module, then use an array value with the key being the module. | Maps foreign keys in other models |
| readonly | FALSE | TRUE/FALSE (boolean) | Sets the model to readonly mode and will not allow inserts, updates and deletes |
Protected Properties
| Preference | Default Value | Options | Description |
|---|---|---|---|
| table_name | Will try and derive from class name minus the suffix | None | The name of the table |
| key_field | id | None | The primary key field |
| normalized_save_data | NULL | None | The original normalized data before it is cleaned for saving |
| cleaned_data | NULL | None | The data after it has been cleaned for saving |
| dsn | NULL | None | An alternative DSN value for connection |
| has_auto_increment | TRUE | TRUE/FALSE (boolean) | Uses auto_increment for table IDs |
| suffix | _model | None | The Data_record suffix before |
| record_class | Will default to the singular version of the Table Class (e.g. examples_model would have default record class of example_model) | None | The name of the Data_record class |
| rules | NULL | None | Validation rules |
| required | NULL | None | Required fields |
| fields | NULL | None | Table fields |
| use_common_query | TRUE | TRUE/FALSE (boolean) | Use the common query method for query |
| validator | NULL | None | The validator object used for validation |
Extending MY_Model
When extending MY_Model, it is recommended to use a plural version of the objects name, in this example Examples, with the suffix of _model (e.g.Examples_model). The plural version is recommended because the singular version is often used for the custom record class (see below for more).
The __construct method requires at least the name of the table to map to in the first argument and then you can optionally set other properties in the second constructor argument (see above for additional properties).
class Examples_model extends MY_Model {
function __construct()
{
parent::__construct('example', array('required' => 'name')); // table name, initialization params
}
}
Most modules in FUEL extend the Base_module_model class, a child of MY_Model, but has some extended functionality needed for modules.
You can also define any of the class properties listed above like so:
class Examples_model extends MY_Model {
public $required = array('name');
public $record_class = 'Example_record';
function __construct()
{
parent::__construct('example'); //table name
}
}
Custom Record Objects
MY_Model adds another layer of control for your models by allowing you to define custom return objects from active record. This gives you more flexibility at the record level for your models. With custom record objects you can:
- Create Derived Attributes
- Lazy Load Other Objects
- Manipulate and Save at the Record Level
When creating a custom record class, it is recommended to use the singular version of the parent model class (so parent models should be plural).
class Examples_model extends MY_Model {
public $required = array('name');
function __construct()
{
parent::__construct('example'); //table name
}
}
class Example_model extends MY_Model {
Custom record model methods go here....
}
Custom record objects are not required. MY_Model will intelligently try and figure out the class name if one is not defined in the parent table model. If the class is not found it will return an array of arrays or an array of standard objects depending on the return_method property of the parent model class. Custom record objects must be defined in the same file that the parent table model is defined.
Create Derived Attributes
With a custom record object, you can derive attributes which means you can create new values from the existing fields or even other models. For example, you have a table with a text field named content that you need to filter and encode html entities and sometimes strip images before displaying on your webpage. Instead of applying the htmlentities and strip_image_tags function each time it is displayed, you can create a new derived attribute on your custom record object like so:
function get_content_formatted($strip_images = FALSE)
{
$CI =& get_instance();
if ($strip_images)
{
$CI->load->helper('security');
$content = strip_image_tags($this->content);
}
$content = htmlentities($this->content);
return $content;
}
Lazy Load Other Objects
Lazy loading of object is used when you don't want the overhead of queries to generate sub objects. For example, if you have a book, model which has a foreign key to an author model, you could create a method on the record class to lazy load that object like this:
function get_spaceship()
{
$ship = $this->lazy_load(array('email' => 'hsolo@milleniumfalcon.com'), 'spacehips_model', FALSE);
return $ship;
}
Manipulate and Save at the Record Level
With custom record objects, you can update attributes and save the record object like so:
$foo = $this->examples_model->find_by_key(1); $foo->bar = 'This is a test'; $foo->save();
Click here to view the function reference for custom record objects
Magic Methods
MY_Model uses PHP's magic methods extensively. This allows for dynamically creating methods that aren't originally defined by the class. Magic methods are used both in the table and custom record classes. In custom record classes, any method prefixed with get_ can also be syntactically written to look like an instance property:
$record->get_content() // can also be written as... $record->contentIn the table class, magic methods are used to find records in interesting ways. For example, you can do something like this (where {} enclose areas where the developer should change to a proper field name):
// to find multiple items
$this->examples_model->find_all_by_{column1}_and_{column2}('column1_val', 'column2_val');
// to find one item
$this->examples_model->find_one_by_{column1}_or_{column2}('column1_val', 'column2_val');
Working with Active Record
MY_Model works alongside active record like so:
...
$this->db->where(array('published' => 'yes'))
$this->db->find_all()
// Is the same as...
$this->db->find_all(array('published' => 'yes'))
Hooks
MY_Model provides hooks that you can overwrite with your own custom code to extend the functionality of your model.
Table class hooks
- on_before_clean - executed right before cleaning of values
- on_before_validate - executed right before validate of values
- on_before_insert - executed before inserting values
- on_after_insert - executed after insertion
- on_before_update - executed before updating
- on_after_update - executed after updating
- on_before_save - executed before saving
- on_after_save - executed after saving
- on_before_delete - executed before deleting
- on_after_delete - executed after deleting
- on_before_post - to be called from within your own code right before processing post data.
- on_after_post - to be called from within your own code after posting data.
Record class hooks
- before_set - executed before setting a value
- after_get - executed after setting a value
- on_insert - executed after inserting
- on_update - executed after updating
- on_init - executed upon initialization