Welcome Guest, Not a member yet? Register   Sign In
Model accessing other Models - best practice
#1

What I wanted to find out is the best practice approach to a model accessing other models.  I've done some research and there doesn't seem to be a general consensus as to whether a model should be able to access other models.  Some people say if the models are "related" then it's fine, other people say models shouldn't talk to other models and such communication should be directed through a controller.  The latter is the approach I took until recently, but then my controllers were becoming "fat" which people say is also bad.

Here's an example of a controller which displays a product.  A product can have an image, with images also being a model of their own (since images can relate to not just products but also other entities):


PHP Code:
class Product extends CI_Controller {

 
   public function index($product_code null) {

 
       // Get the product model
        $product $this->product_model->get($product_code);

        if ($product) {
 
           // Get the product's image
            $product['image'] = $this->image_model->get($product_code"product");

 
           // Display the product
            $this->load->view('product'$product);
        } else {
            // Display 404 error
        }
 
   }



However, this is a fairly basic example.  In reality a product might have an image, a set of attributes, a set of bullet points, a list of related products and some custom fields.  Some of these might be their own models, others might be part of the product model.  In any case, my controller now looks like this:


PHP Code:
class Product extends CI_Controller {

    public function index($product_code null) {

 
       // Get the product model
        $product $this->product_model->get($product_code);

        if ($product) {

 
           // Get the product's image
            $product['image'] = $this->image_model->get($product_code"product");

 
           // Get the product's custom fields
            $product['custom_fields'] = $this->customfield_model->get_custom_fields($product_code"product");

 
           // Get the product's attributes
            $product['attributes'] = $this->product_model->get_attributes($product_code);

 
           // Get the product's bullet points
            $product['bullets'] = $this->product_model->get_bullets($product_code);

 
           // Get the product's related products
            $product['related_products'] = $this->product_model->get_related_products($product_code);

 
           // Display the product
            $this->load->view('product'$product);
        } else {
            // Display 404 error
        }
    }




Whilst this is OK I have to make a lot of different calls to various models whenever I want to fetch a product, and the controllers get quite cluttered.

An alternative approach I've taken recently is for the product model to have access to all of the associated models, and to pass in a set of arguments to determine which elements I want to get.  This means I don't need to query sub-tables and other models unnecessarily if I only wanted to get, say the product name and nothing else:


PHP Code:
class Product extends CI_Controller {

    public function index($product_code null) {

 
       // Arguments specifying which product details we want to fetch
        $args = array(
            'fields'           => array('product_name''product_description'), // Get product_name and product_description fields
            'image'            => true// Get the product's image
            'custom_fields'    => true// Get the product's custom fields
            'attributes'       => false// Don't bother getting attributes on this occasion
            'bullets'          => true// Get product's bullet points
            'related_products' => true// Get product's related products
        );

 
       // Get the product based on specified arguments
        $product $this->product_model->get($product_code$args);

 
       // Display the product
        if ($product) {
            $this->load->view('product'$product);
        } else {
            // Display 404 error
        }
    }


I realise there is no right or wrong answer, but I was looking for some guidance as to the best way of handling this.  The only downside I can see with the final example is that models have to load each other and then become dependent on each other.

The disadvantage with the first and second example is that the controllers become quite cluttered - you can't get a complete product with a single call to a model.  You also have to remember which models to query rather than just passing in a bunch of arguments.

Thanks in advance.
Reply
#2

Why not use a MY_Model and extend from it?

All related code used in all models placed into the MY_Model.
What did you Try? What did you Get? What did you Expect?

Joined CodeIgniter Community 2009.  ( Skype: insitfx )
Reply
#3

Model calling models is fine.
Reply




Theme © iAndrew 2016 - Forum software by © MyBB