Jeśli piszesz większy projekt, to po pewnym czasie może się okazać, że każdy z Twoich modeli wygląda podobnie – przynajmniej w pewnej części. Aplikacje internetowe, to w dużej mierze często operacje typu CRUD, których kod jest łatwy do przewidzenia. Dlatego warto w takich momentach zastosować się do metody DRY i spróbować refaktoryzować swój model. W tym celu możemy stworzyć klasę MY_Model w katalogu application/core z „uniwersalnym” kodem.
Oczywiście poniższy przykład będzie przedstawiał chyba jeden z najprostszych możliwych sposobów. Do solidnych i gotowych rozwiązań w tej kwestii przejdziemy na końcu tego wpisu. Ten kod potraktuj proszę tylko jako wprowadzenie w temat.
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class MY_model extends CI_Model
{
protected $_table;
public function get_all($where = NULL)
{
if ($where !== NULL)
{
$this->db->where($where);
}
return $this->db->get($this->_table)->result_array();
}
public function count_all($where = NULL)
{
if ($where !== NULL)
{
$this->db->where($where);
}
return $this->db->count_all_results($this->_table);
}
public function get($where)
{
return $this->db->where($where)->get($this->_table)->row_array();
}
public function add($data)
{
$this->db->insert($this->_table, $data);
return $this->db->insert_id();
}
public function update($where, $data)
{
return $this->db->where($where)->update($this->_table, $data);
}
public function delete($where)
{
$this->db->where($where)->delete($this->_table);
return $this->db->affected_rows();
}
}
Zobaczmy teraz jak można wykorzystać powyższą klasę w praktyce. Na początek tworzymy standardowy plik modelu, który jednak będzie rozszerzał klasę MY_Model, a nie jak zazwyczaj klasę CI_Model:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Post_model extends MY_Model
{
protected $_table = 'posts';
}
Tak jest, to tyle jeśli chodzi o model. Teraz pora na kontroler (z góry przepraszam za niektóre długie nazwy metod, ale miało być „obrazowo”):
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Posts extends CI_Controller
{
public function __construct()
{
parent::__construct();
$this->load->model('post_model');
}
public function get_all_posts()
{
$this->post_model->get_all();
}
public function get_all_accepted_posts()
{
$this->post_model->get_all(array('is_accepted' => 1));
}
public function add_post()
{
$data = array(
'name' => 'renholder',
'comment' => 'Komentarz'
);
$this->post_model->add($data);
}
public function update_post($id)
{
$data = array(
'comment' => 'Zmieniony komentarz'
);
$this->post_model->update(array('id' => $id), $data);
}
public function delete_post($id)
{
$this->post_model->delete(array('id' => $id));
}
}
Mam nadzieję, że powyższy przykład wykorzystania klasy MY_Model mówi sam za siebie.
Oczywiście istnieją gotowe, bardziej rozbudowane rozszerzenia klasy modelu. Zaproponuję Wam tutaj dwa z nich. Autorem pierwszego jest Jamie Rumbelow (https://github.com/jamierumbelow/codeigniter-base-model), a drugiego Jesse Terry (https://github.com/jesseterry/CodeIgniter-CRUD-Model). Oba projekty dysponują dokumentacją, która z pewnością ułatwi Wam rozpoczęcie pracy.
Co więc daje nam wykorzystanie rozszerzonej klasy modelu? Przede wszystkim możemy dzięki temu pracować szybciej i uprościć nasz kod.
Jaką mamy alternatywę dla używania własnej/gotowej klasy modelu? Odpowiedzią może się okazać ORM, ale to już temat na zupełnie inny wpis.
Kurde ze tez ja o tym -> https://github.com/jesseterry/CodeIgniter-CRUD-Model,
nigdy wczesniej nie slyszalem. Codeigniter-base-model jest wg. mnie strasznie toporny. Dzieki.
Kwestia gustu – oba modele różnią się trochę jeśli chodzi o możliwości. Ja akurat preferuję rozwiązanie Jamie’go – ma po prostu opcje których szukam.
Cześć moim skromnym zdaniem najlepsza forma dostępu do bazy danych i wykonywania na niej operacji to użycie biblioteki między innymi
http://www.phpactiverecord.org/
Zobaczcie sobie proste przykłady a się przekonacie …
Piękno sprawy to gotowy zestaw wywołan (w tym dynamicznych np find_by_nazwapola() )
Albo po prostu users::find(). // zakładając ze mamy klasę users (oraz tablice w bazie)
Ps/ biblioteka wzorowana na ryby on rails , i super działa z codeigniter.
pozdrawiam
Dzięki za komentarz. Oczywiście jest to jedna z możliwości, chociaż to już rozwiązanie typu ORM.