Created
November 4, 2011 09:37
-
-
Save toopay/1339003 to your computer and use it in GitHub Desktop.
Gas ORM - Convention and Examples
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// By default, if you use User as your model name, | |
// you may should named this file user_gas.php within your models directories | |
// You can change '_gas' suffix in gas.php under config | |
class User extends Gas { | |
// If your table name different with your model name, specify it | |
// otherwise, you didnt need to declare this property | |
public $table = 'person'; | |
// If your primary key isn't 'id', specify it | |
// otherwise, you didnt need to declare this property | |
public $primary_key = 'person_id'; | |
// Here you can define your table relationship | |
// otherwise, you didnt need to declare this property | |
public $relations = array( | |
// Gas support 3 types relationship, one-to-one, one-to-many and many-to-many | |
// In this example, user have one wife, many kids and many (and belongs to) jobs | |
// If you define a relationship, your corresponding table, should have one too, | |
// which represent your tables relationship. | |
// eg : by bellow seting, your 'wife' and 'kid' tables should have 'belongs_to' | |
// while your 'job' table should have 'has_and_belongs_to' | |
// means each user record have one record in 'wife' table, | |
// identified with foreign key in 'wife' table | |
'has_one' => array('wife' => array( | |
// By default, Gas will assume that your foreign key is 'user_id' | |
// otherwise, you should define it on 'foreign_key' | |
'foreign_key' => 'person_id' | |
// NOTE : Make sure your 'wife' table also have this foreign key | |
)), | |
// means each user record have many records in 'kid' table, | |
// identified with foreign key in 'kid' table | |
'has_many' => array('kid' => array( | |
// By default, Gas will assume that your foreign key is 'user_id' | |
// otherwise, you should define it on 'foreign_key' | |
'foreign_key' => 'person_id' | |
// NOTE : Make sure your 'wife' table also have this foreign key | |
), | |
'role' => array( | |
// If you try to connecting three (or more) tables via intermediate | |
// table, which also have its own id and other values, use this | |
// option. Notice that while you use this, it refer to a gas model, | |
// so in this case, you should create 'user_role' model | |
'through' => 'user_role', | |
// By default, Gas will assume that your foreign key is 'user_id' | |
// otherwise, you should define it on 'foreign_key' | |
'foreign_key' => 'u_id', | |
)), | |
// means each user have many records in 'job' table, | |
// identified with foreign key in pivot table which should be : 'job_user' table | |
'has_and_belongs_to' => array('job' => array( | |
// By default, Gas will assume that your foreign key is 'user_id' | |
// otherwise, you should define it on 'foreign_key' | |
'foreign_key' => 'person_id', | |
// NOTE : Make sure you set up foreign key in 'job' table as well, | |
// but, because this is many-to-many, 'job' table foreign key | |
// should represent job FK in the pivot table, eg : 'jobs_id', 'j_id' // and so on | |
// By default, Gas will assume that your pivot table is 'job_user' | |
// otherwise, you should define it on 'foreign_table' | |
'foreign_table' => 'j_u', | |
// NOTE : Make sure your 'job' table also have this foreign table | |
)), | |
); | |
// _init is works like constructor, so if you need to declare/set some properties, | |
// or loading some library/config or anything else, which you may used later in your methods, | |
// do it here | |
// If you decide to perform validation before insert/update a record | |
// you can define each field rules here | |
// otherwise, you didnt need to declare this method and _field property | |
function _init() | |
{ | |
// Here you can define your fields types and validation rules | |
$this->_fields = array( | |
// By default, Gas support 4 common datatypes : auto, char, int, email | |
// auto : for autoincrement field | |
// char : for CHAR or VARCHAR field | |
// int : for integer/numerical field | |
// email : same with valid_email rule at CI validation rule | |
// And field() method support maxlength short hand, | |
// all you have to do is put some maxlength number inside a brackets [] | |
'id' => Gas::field('auto[3]'), | |
'name' => Gas::field('char[40]'), | |
'email' => Gas::field('email'), | |
// If you need to implement some standard CI validation rules, | |
// somethinf like : required, matches, decimal and so on | |
// put in an array as second parameter. | |
'username' => Gas::field('char[10]', array('callback_username_check')), | |
); | |
} | |
// callback which will execute, before going to validation process | |
function _before_check() {} | |
// callback which will execute, after validation process | |
function _after_check() {} | |
// callback which will execute, before going to write (INSERT or UPDATE) process | |
function _before_save() {} | |
// callback which will execute, after write (INSERT or UPDATE) process | |
function _after_save() {} | |
// callback which will execute, before going to DELETE process | |
function _before_delete() {} | |
// callback which will execute, after DELETE process | |
function _after_delete() {} | |
// If you have some custom callback function in your validation rules | |
// your callback function should follow this pattern | |
// FIRST : it has to expected two parameter, the first parameter | |
// will automatically populated by Gas | |
// The second parameter is the value to check | |
public function username_check($field, $val) | |
{ | |
// in this case, username cannot contain 'me' as its value | |
if($val == 'me') | |
{ | |
// SECOND : this is slightly different way, to set your validation message | |
// Gas using static method set_message() to replace the original set_message, | |
// from CI validation class, but it actually work with the same way, | |
// except, you should put $field as third parameter. | |
self::set_message('username_check', 'The %s field cannot fill by "me"', $field); | |
return FALSE; | |
} | |
return TRUE; | |
} | |
// If you need extra logic in your controller | |
// and it is potentially will make your controller fat | |
// avoid, by create your own custom finder function | |
public function all_admin() | |
{ | |
// Here you can use factory method to find some specific record(s) | |
return Gas::factory($this->model())->join_role('role.id = user.role') | |
->where('role', 1) | |
->or_where('role', 2) | |
->order_by('id', 'asc') | |
->all(); | |
} | |
// Then in any controller, anytime you need to retrieve it | |
// $admins = Gas::factory('user')->all_admin(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// This is an examples, how you can use finder method, | |
// from your Gas model, in your controller. | |
class Gas_finder extends CI_Controller { | |
public function index() | |
{ | |
// You can instantly using some Gas model | |
// without instantiate it, by using factory method | |
$users = Gas::factory('user')->all(); | |
// To reduce keystroke, just instantiate user model once | |
$user = new User; | |
// Then you can implement all finder method | |
// Get the first record, based by primary key | |
// You can specify some column, eg : $user->first('email') | |
$firstuser = $user->first(); | |
// Gas have to_array() and to_json() | |
// as a helper method, while you want to output | |
// your record | |
var_dump($firsuser->to_array()); | |
// Get the last record, based by primary key | |
// You can specify some column, eg : $user->last('name') | |
$lastuser = $user->last(); | |
// Get max for primary key | |
// In all aggregator method : max, min, avg, sum | |
// You can specify some column, eg : $user->max('money') | |
$max = $user->max(); | |
$min = $user->min(); | |
// Like CI AR, Gas inherit aliasing column name as well | |
$avg = $user->avg('id', 'average_id'); | |
$sum = $user->sum('id', 'sum_of_id'); | |
// Get a record, based by primary key | |
$someuser = $user->find(1); | |
// Get a set of records, based by primary key | |
$someusers = $user->find(1, 2, 3); | |
// Get a set of records, based by other column | |
// eg : you have email, name, username at your user table | |
// then, you can use find_by_name or find_by_username too | |
$someusers = $user->find_by_email('johndoe@yahoo.com'); | |
// find_by will always result an array. If you want Gas to return | |
// a first matched record, directly as an object, pass limit number as second parameter | |
$someuser = $user->find_by_username('administrator', 1); | |
// The huge advantages, by using Gas you can fully utilize CI AR as well : | |
// almost all CI active record method, can chained with Gas finder method. | |
// Beside all(), find() and find_by_column() | |
// Gas have find_where() and find_where_in(), eg : | |
// | |
// $someusers = $user->where_in(array('role' => array(1,2)))->find_where(array('active' => 1)); | |
// | |
// $someusers = $user->where('active', 1)->find_where_in(array('role' => array(1,2))); | |
$someusers = $user->group_by('email')->min('money'); | |
$someusers = $user->like('email', 'yahoo.com')->all(); | |
$somejoinedusers = $user->left_join_job('job.id = user.id')->all(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// This is miscellaneous method which supported by Gas. | |
// most of them actually inherit CI AR, with shorter keystroke | |
// or common logic combination | |
class Gas_misc extends CI_Controller { | |
public function index() | |
{ | |
// Sometime, you are forgot all of existed coloumn in a table | |
// use list_fields | |
var_dump(Gas::factory('user')->list_fields()); | |
// Suppose you are about save a record | |
$_POST = array( | |
'id' => null, | |
'name' => 'Mr. Foo', | |
'email' => 'foo@world.com', | |
'username' => 'foo' | |
); | |
$new_user = new User; | |
// this will mapped $_POST data with fields rules | |
// you define in _init method in user model respectively | |
$new_user->fill($_POST); | |
// to see all data which has already set | |
// use filled_fields | |
var_dump($new_user->filled_fields()); | |
// If everything seems ok, you can continue to save the record | |
$new_user->save(); | |
// to get the last executed query, use last_sql() | |
var_dump($new_user->last_sql()); | |
// Often, you need to know the last id created by INSERT operation | |
// use last_id() | |
$last_created_id = $new_user->last_id(); | |
// I'm not a huge fan of JOIN operation : ITS EXPENSIVE! | |
// but for you, who love it, Gas provide easier shorthand | |
// so you can craft your JOIN statement easier | |
// Gas inherit from CI AR, so available shorthand were : | |
// 'left', 'right', 'outer', 'inner', 'left outer' and 'right outer' | |
// you can JOIN-ed some table/model as follow : | |
$someusers = Gas::factory('user')->left_join_phone('phone.user_id = user.id')->all(); | |
$someusers = Gas::factory('user')->left_outer_join_sandals('sandals.id = user.sandal_id')->all(); | |
// to get all executed query, use all_sql() | |
var_dump(Gas::factory('user')->all_sql()); | |
// Gas support multiple connection, so you can switch to other database | |
// by default, Gas will use 'default' group, specified in your database.php under config folder | |
// Switching to other database just need a dsn string or group connection name (which you specified | |
// in database.php under config directory) | |
// You can specify the dsn string | |
Gas::connect('mysql://root:password@localhost/my_db'); | |
// This will search from user table at 'my_db' database | |
var_dump(Gas::factory('user')->find(1)); | |
// You can specify the connection group name | |
Gas::connect('develop'); | |
// This will search from user table at database | |
// specified by your 'develop' group configuration | |
var_dump(Gas::factory('user')->find(1)); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// This is an examples, how you can utilize your table relationship | |
// from your Gas model, in your controller. | |
// You may put some part/fraction of this code, | |
// to your model as custom function instead write it in your controller | |
// this is just an example, how you would utilize table relationship in Gas ORM | |
class Gas_relationship extends CI_Controller { | |
public function index() | |
{ | |
// One-To-One : Will return an object of wife, which have user_id = 1 | |
$somewife = Gas::factory('user')->find(1)->wife; | |
// Each child Gas instance which retrieved, can be directly process | |
// with write operation, eg : update | |
$somewife->hair_colour = 'Brunette'; | |
$somewife->save(); | |
// One-To-Many : Will return an array of kid object, which have user_id = 1 | |
$somekids = Gas::factory('user')->find(1)->kid; | |
// for one-to-many or many-to-many relationship | |
// Gas will always return an array, so you proceed it as follow | |
foreach ($somekids as $kid) | |
{ | |
// Here you can do whatever you want to do with 'kid' instance | |
echo $kid->name; | |
if (strpbrk($kid->name, 'Doe')) | |
{ | |
// you can do write operation as well | |
$kid->name = 'John Doe\'s son(s)' | |
$kid->save(); | |
} | |
} | |
// Many-To-Many : Will return an array of job object, | |
// based by pivot table (job_user), which have user_id = 4 | |
$somejobs = Gas::factory('user')->find(4)->job; | |
// Eager Loading : Will return an array of user object, | |
// alongside with each relational table with WHERE IN(N+1) | |
$allinone = Gas::factory('user')->with('wife', 'kid', 'job')->all(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// This is an examples, how you perform transaction, | |
// at your Gas model. | |
class User extends Gas { | |
function _init() | |
{ | |
$this->_fields = array( | |
'id' => Gas::field('auto[3]'), | |
'name' => Gas::field('char[40]') | |
); | |
} | |
public function dummy_trans() | |
{ | |
// notice that $this->model() will return | |
// your table/model name automatically, | |
// so you doesn't need to write 'user' | |
// inside factory method, whithin your model | |
$user = Gas::factory($this->model()); | |
// This is transaction pointer, everyting below this | |
// will treated as transactional query(s) | |
$user->trans_start(); | |
// Here you can have some queries executed using query() method | |
for($i = 5;$i < 10;$i++) | |
{ | |
$user->query('INSERT INTO `'.$this->model().'` (`id`, `name`) VALUES ('.$i.', \'user_'.$i.'\')'); | |
} | |
for($i = 5;$i < 10;$i++) | |
{ | |
// Here i just show you, how Gas can support AR pattern in transaction blocks | |
$new_user = Gas::factory($user->model())->find($i); | |
$new_user->fill(array('name' => 'person_'.$i))->save(); | |
} | |
// If something goes wrong | |
if ($user->trans_status() === FALSE) | |
{ | |
// will produce SQL : "ROLLBACK" | |
$user->trans_rollback(); | |
} | |
else | |
{ | |
// If everything ok | |
// will produce SQL : "COMMIT" | |
$user->trans_commit(); | |
} | |
// If above transaction works fine, then this will find one result | |
$user9 = Gas::factory('user')->find(9); | |
// Should be echoing 'person_9' | |
echo $user9->name; | |
} | |
} | |
// To call this, from your controller, you only need 1 line : | |
// Gas::factory('user')->dummy_trans(); | |
// That should echoing 'person_9', for example. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// This is an examples, how you can use write method, | |
// from your Gas model, in your controller. | |
// You better put this write operation block, to your model, | |
// as custom function instead write it in your controller, | |
// this is just an example, how you would doing some inserting data process in Gas ORM. | |
class Gas_write extends CI_Controller { | |
public function index() | |
{ | |
// Suppose you have this data from some form, to create new user | |
$_POST = array( | |
'id' => null, | |
'name' => 'Mr. Foo', | |
'email' => 'foo@world.com', | |
'username' => 'foo' | |
); | |
$new_user = new User; | |
// this will mapped $_POST data with fields rules | |
// you define in _init method in user model respectively | |
$new_user->fill($_POST); | |
// By default, Gas not enforce you to use validation process | |
// so if you want to invoke and perform validation process | |
// based by rule you specified in your model, pass TRUE in save() | |
if ( ! $new_user->save(TRUE)) | |
{ | |
$insert_result = $new_user->errors(); | |
} | |
else | |
{ | |
$insert_result = '<p>New user succesfuly created.</p>'; | |
} | |
echo $insert_result; | |
// From last created record, using 'last_id' method, | |
// eg : will return '1', because above is first record | |
$new_id = $new_user->last_id(); | |
// Create new user instance with last created record | |
$recent_user = Gas::factory('user')->find($new_id); | |
// Suppose you have this array as data | |
$update_data = array( | |
'name' => 'Mr. Bar', | |
'email' => 'bar@world.com' | |
); | |
// you can use fill, to set your model data | |
// and set those array as $_POST, by pass TRUE | |
// as second parameter | |
$recent_user->fill($update_data, TRUE); | |
// or directly set it like bellow | |
$recent_user->username = 'bar'; | |
if ( ! $recent_user->save(TRUE)) | |
{ | |
// Like CI AR, you could use prefix and suffix to wrap errors string | |
// generated by validation process | |
$update_result = $new_user->errors('<p class="error">', '</p>'); | |
} | |
else | |
{ | |
$update_result = '<p>New user succesfuly created.</p>'; | |
} | |
echo $update_result; | |
// To delete something, you can directly assign id, or 'delete' will see through your recorded logic, eg : | |
$now_user = Gas::factory('user')->find($new_id); | |
// Just ensure that data has been updated | |
if ($now_user->username != 'bar') | |
{ | |
// This will delete user 1 | |
$now_user->delete(); | |
} | |
// You can delete several records, based by their primary key too | |
Gas::factory('user')->delete(1, 2, 3); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment