You can do it however you like. A model does not have to be limited to a single table, you can JOIN, UNION and UPDATE whatever table you like from wherever.
To further Donny Kurnia's suggestions, a very good existing MY_Model has already been written by Jamie Rumbleow (with a few contributions from myself ofc) which contains several get, count, insert, etc methods. These allow you to do most basic CRUD requirements simple by creating an empty model that extends from MY_Model.
That is great for one-table get/insert/delete but when it comes to creating methods that require joining, the best thing to do is just write them yourself.
When joining tables you will need to set WHERE's based on table names/aliases and you will find conflicting field names if you are not careful, meaning that creating a general solution to manage all joins queries from MY_Model is either going to be VERY difficult or just a mess.
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
class Tickets_m extends MY_Model
{
// Basic get, insert, delete stuff handled in MY_Model
function get_client_tickets($category_slug = '')
{
$this->db->select('t.*')
->select('c.title as category_title, c.slug as category_slug')
->select('p.name as priority_name')
->join('categories c', 'c.id = t.category_id')
->join('priorities p', 'p.id = t.priority_id')
->from('tickets t')
->where('c.client_id', CLIENT_ID);
if($category_slug)
{
$this->db->where('c.slug', $category_slug);
}
return $this->db->get()->result();
}
function get_client_ticket($id)
{
$this->db->select('t.*')
->select('c.title as category_title, c.slug as category_slug')
->select('p.name as priority_name')
->join('categories c', 'c.id = t.category_id')
->join('priorities p', 'p.id = t.priority_id')
->from('tickets t')
->where('c.client_id', CLIENT_ID)
->where('t.id', $id);
return $this->db->get()->row();
}
function insert($ticket)
{
$this->load->helper('date');
$ticket['created_on'] = now();
return parent::insert($ticket);
}
}
Here is an example of a very simple model I am working with at the moment which shows me combining the use of MY_Model for get, get_by, insert, update with some custom methods which have joins and extra data in them.
You can also see me overloading insert() to automatically add in the created date without needing to set it in each controller that may be creating or updating the ticket.
If you need even more magic auto-matic joinery madness, try ORM with something like Doctrine or DataMapper