Rozszerzanie klasy CI_Model

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.

5 komentarzy do wpisu „Rozszerzanie klasy CI_Model”

    • 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.

  1. 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.

Dodaj komentarz

This site uses Akismet to reduce spam. Learn how your comment data is processed.