Welcome Guest, Not a member yet? Register   Sign In
Creating multiple instances of a model
#1

(This post was last modified: 04-28-2016, 07:54 AM by CINewb.)

Hi there

I am wondering, how do you create multiple instances of a model?

For example:


PHP Code:
foreach ($query->result_array() as $row) {
    $this->load->model('customer_model');
    $this->customer_model->setName($row['name']);
    $customers[] = $this;



With the above example, what I end up with is every customer having the same name because each element of the $customers array is referencing the same instance.

The way I've figured out to do it is:


PHP Code:
$this->load->model('customer_model');
foreach (
$query->result_array() as $row) {
    $c = new Customer_model();
    $c->setName($row['name']);
    $customers[] = $c;



Is the second example acceptable, or does it break CodeIgniter best practice?

Thank you
Reply
#2

The first example is never a good idea. If a model is already loaded, it will not load again.
The second example isn't a good idea either. It makes your code unnecessarily complex.

Please, explain what you are trying to do. It appears to me that you want to fetch a list of customers from your database, is that correct?
Reply
#3

(04-28-2016, 07:17 AM)Wouter60 Wrote: The first example is never a good idea. If a model is already loaded, it will not load again.
The second example isn't a good idea either. It makes your code unnecessarily complex.

Please, explain what you are trying to do. It appears to me that you want to fetch a list of customers from your database, is that correct?

Yes, that's correct.  But each customer should be an object/model with access to the relevant class functions.
Reply
#4

Your second example is the practice I would follow.
Once a model has been loaded, you can create new instances as needed.
I don't agree that it makes your code unnecessarily complex ... it "just is".
Reply
#5

(04-28-2016, 07:17 AM)Wouter60 Wrote: The second example isn't a good idea either. It makes your code unnecessarily complex.

No it doesn't.
Reply
#6

(This post was last modified: 04-28-2016, 09:53 AM by kilishan.)

Personally, I would separate the Customer entity from the model itself. What I mean is that I would have two classes: Customer and Customer_model. The model would be responsible for all interactions with the database. Then, the Customer class would represent a single customer. It would have any additional business logic needed inside of it, functions to get related entities, etc. You can have the query result object return custom classes, so your code would simplify into something like this:

Code:
// You need to load the class into memory somehow,
// unless you're using Composer and namespacing it...
$this->load->library('Customer');

// Load the model and the query results.
$this->load->model('customer_model');
$query = $this->customer_model->findActive();

// Returns an array of Customer instances.
$customers = $query->result('Customer');
Reply
#7

Thanks for all of your replies.  I am taking all of this in.


The reason I came up with what I did in the second example is because I envisage doing something like this:


PHP Code:
$this->load->model('customer_model');
foreach (
$query->result_array() as $row) {
   $c = new Customer_model();
   $c->create($row);
   $customers[] = $c;



Then in the view I could do something like this:


PHP Code:
foreach ($customers as $customer) {

   if ($customer->isBirthday()) :

       echo 'It is ' $customer->name ' birthday today';

   }



So in other words, the $customers array contains a list of customer_model objects, each one having access to all of the methods within the customer_model object.


This kind of leads on to another question, which is how should a list of objects be treated?


For example, a single "customer" is an object or a model.  But what is a list of customers?  I think in some patterns this is referred to as a "repository" or "collection" perhaps.


My thinking is that "customer" could be a model (featuring name, dob, email, etc), and "customer_repository" could be a separate model (list of customers, total number of customers, etc).  This would however mean that $this->customer_repository_model->getList() would need to access $this->customer_model->get() to get the individual customers, and I'm not sure whether or not a model should access another model?

(04-28-2016, 09:51 AM)kilishan Wrote: Personally, I would separate the Customer entity from the model itself. What I mean is that I would have two classes: Customer and Customer_model. The model would be responsible for all interactions with the database. Then, the Customer class would represent a single customer. It would have any additional business logic needed inside of it, functions to get related entities, etc. You can have the query result object return custom classes, so your code would simplify into something like this:

Interesting, I will digest what you just said and have a think about it
Reply
#8

(04-28-2016, 10:16 AM)CINewb Wrote: For example, a single "customer" is an object or a model.  But what is a list of customers?  I think in some patterns this is referred to as a "repository" or "collection" perhaps.


My thinking is that "customer" could be a model (featuring name, dob, email, etc), and "customer_repository" could be a separate model (list of customers, total number of customers, etc).  This would however mean that $this->customer_repository_model->getList() would need to access $this->customer_model->get() to get the individual customers, and I'm not sure whether or not a model should access another model?

The example I gave is based on the Repository pattern. It basically states that you have an Entity and a Repository. The Entity exists completely on it's own and only represents the entity and it's business rules. It doesn't care how you get or save the data, but lives in its own little silo. The Repository, then, is responsible for creating and saving the items. In CI terms, that's the Model. The benefit is that you can always change out how the data is retrieved and saved, or even where it's saved, without affecting the application since the application only relies on Entity.

As for Collections, the are what they sound like, collections of that item. Often times, they will have additional functionality that is helpful, but I've found that 90% of the time an array works just as well as a Collection, with less abstractions, less work to duplicate the same features you get by having an array, less overhead, etc. Sometimes they're helpful, but I personally stay away from worrying about that until you need it.
Reply
#9

(04-28-2016, 10:45 AM)kilishan Wrote: As for Collections, the are what they sound like, collections of that item. Often times, they will have additional functionality that is helpful, but I've found that 90% of the time an array works just as well as a Collection, with less abstractions, less work to duplicate the same features you get by having an array, less overhead, etc. Sometimes they're helpful, but I personally stay away from worrying about that until you need it.

I think I follow.  So, if a collection is just an array of customers in this example, what creates the array?  The Customer_model ?  If so that's fine, I just wasn't sure whether a model should be responsible for both single entities, and also a collection of those entities.
Reply
#10

(04-28-2016, 09:51 AM)kilishan Wrote: Personally, I would separate the Customer entity from the model itself. What I mean is that I would have two classes: Customer and Customer_model. The model would be responsible for all interactions with the database. Then, the Customer class would represent a single customer. It would have any additional business logic needed inside of it, functions to get related entities, etc. You can have the query result object return custom classes, so your code would simplify into something like this:

Code:
// You need to load the class into memory somehow,
// unless you're using Composer and namespacing it...
$this->load->library('Customer');

// Load the model and the query results.
$this->load->model('customer_model');
$query = $this->customer_model->findActive();

// Returns an array of Customer instances.
$customers = $query->result('Customer');

You can create multiple instances of a library? I thought Libraries were singletons as well.
Reply




Theme © iAndrew 2016 - Forum software by © MyBB