![]() |
Populating an array of objects using CI's load->model() functionality - Printable Version +- CodeIgniter Forums (https://forum.codeigniter.com) +-- Forum: Archived Discussions (https://forum.codeigniter.com/forumdisplay.php?fid=20) +--- Forum: Archived Development & Programming (https://forum.codeigniter.com/forumdisplay.php?fid=23) +--- Thread: Populating an array of objects using CI's load->model() functionality (/showthread.php?tid=29782) |
Populating an array of objects using CI's load->model() functionality - El Forum - 04-21-2010 [eluser]paulkmoore[/eluser] Hi all - newbie post, so please feel free to redirect me if appropriate I am trying to create an array of objects each of which is an instantiation of a Model. For context, I am modelling financial transactions in a hierarchy with a typical header and details relationship. I have a Model for the tx header, and a model for tx detail, where one tx header has many tx detail subordinates. I'd like to create the tx header and create an array of tx detail objects to represent the 'full' transaction. I can instantiate single instances of both models within the controller fine, but I'm struggling to load multiple tx detail objects. If I've understood the CI internals correctly all Models loaded using the load->model construct are mapped to the CI superobject (which is a Singleton), and therefore each object will be unique by name. This is set out in Loader.php which allows for the object to be reference by a specified name (as per the excellent CI user guide) - however, the name is required to be a string and therefore I am unable to call the load->model with an array element for a name. i.e. $this->load->model('my_tx_detail_model', "txd[3]"); (reasonably) fails. Is this a limitation of the CI superobject (singleton) design choice (flowed through to Loader.php), or is there some other approach I could be using to instantiate multiple Model objects? I've seen some reference to splobjectstorage, but again not sure whether this reasonably fits with the CI singleton or not. Many thanks in advance Paul Populating an array of objects using CI's load->model() functionality - El Forum - 04-21-2010 [eluser]n0xie[/eluser] Have you tried: Code: $txd = array('somename', 'someothername'); Or maybe I didn't understand the question. Populating an array of objects using CI's load->model() functionality - El Forum - 04-21-2010 [eluser]Dan Horrigan[/eluser] n0xie: I could be wrong, but I believe that the second load of the same model would just be a reference to the first...no? EDIT: No, I was wrong, it creates a new object every time, provided you give it a different name each time. Anyways, why would you want to do this? You wouldn't want to load the model multiple times. That is not efficient. You should have the detail model return all the details for a given header. It is easy and efficient: Code: //WARNING: UNTESTED CODE Intended as example only You could also create 2 libraries (not models), one called TxHeader and the other TxDetail. Then the TxHeader can contain an array of TxDetail objects. Either way is better than trying to load the same model a bunch of times. Dan Populating an array of objects using CI's load->model() functionality - El Forum - 04-21-2010 [eluser]paulkmoore[/eluser] n0xie / Dan Many thanks for the prompt replies - I really appreciate it. Addressing the responses somewhat in turn: n0xie - this would and does work but requires me to define the array of strings up front. I'm trying to load a number of detail records and don't know how many I'll have in advance. I appreciate that this would give the load->model function a string to work with however. Dan - agree with your EDIT - the Loader.php allows for a unique name. To respond to the 'why would you want to do this point' I am using the models as objects to represent the table rows. i.e. each model has a set of properties (the columns from the table) and methods to get/set from the database, and any other methods appropriate to the object. I hear (somewhat) the point about efficiency but to be honest the Model doesn't seem to be much overhead (given analysis of the Loader.php) and frankly if I create other objects that then instantiate the model(s) I'll be in a not dissimilar position. I am trying to create something of a container class that will manage the header and multiple details records, and frankly I'm not sure whether this should be a Model or not. It's certainly not a Controller and doesn't feel like a library. Perhaps I should create a business_objects directory or similar - but I somewhat concerned about moving from the existing MVC primitives. I'll take a more detailed look at your proposed example and get back to you. Thanks both Paul Populating an array of objects using CI's load->model() functionality - El Forum - 04-21-2010 [eluser]Dan Horrigan[/eluser] [quote author="paulkmoore" date="1271885581"]n0xie / Dan I am trying to create something of a container class that will manage the header and multiple details records, and frankly I'm not sure whether this should be a Model or not. It's certainly not a Controller and doesn't feel like a library. Perhaps I should create a business_objects directory or similar - but I somewhat concerned about moving from the existing MVC primitives. [/quote] A library is your best bet (a library is just a fancy name for a class anyway). Create a Details class that has all the properties you need. Then your container class can have an array of Detail classes. Each Details object would be a row from the database. The libraries can access the models that actually interface with the db (as long as you use use the get_instance() function). Because the 2 classes are so closely tied, you can keep them both in the same file, that way you just load 1 library into your controller. Dan Populating an array of objects using CI's load->model() functionality - El Forum - 04-21-2010 [eluser]vitoco[/eluser] [quote author="Dan Horrigan" date="1271886118"] A library is your best bet (a library is just a fancy name for a class anyway). Create a Details class that has all the properties you need. Then your container class can have an array of Detail classes. Each Details object would be a row from the database. The libraries can access the models that actually interface with the db (as long as you use use the get_instance() function). Because the 2 classes are so closely tied, you can keep them both in the same file, that way you just load 1 library into your controller. Dan[/quote] Why use get_instance() from a library in order to access databases, if models do that with $this->db ??. I think, that you must use one Model, or in the worst case, extends one model from the other, so you can get access to db, and return the data as you need. MODEL 1 Code: Class MTx_detail extends Model Code: Class MTx extends MTx_detail IN THE CONTROLLER Code: ... Populating an array of objects using CI's load->model() functionality - El Forum - 04-21-2010 [eluser]Dan Horrigan[/eluser] I should have worded my response better. You wouldn't access the db directly from the library, you would still use a model, you would just call the model methods from the library. On your examples you gave...I do not agree, however, that does not make it wrong. It is just not my style. If you are going to go strictly models, I would do as I did in my original post. I am done with this topic. Paul, there are a million ways to skin a cat, so pick the way that fits your style best and go for it (not skin a cat...that is just a metaphor :-)). Dan Populating an array of objects using CI's load->model() functionality - El Forum - 04-27-2010 [eluser]paulkmoore[/eluser] Dan et al Thanks for all the feedback - I really appreciate it. Here's what I have concluded: The reason I was getting into a mess with i) multiple instances of Models and ii) hierarchies of Models is that I was trying to implement object aggregation of the Transaction header and details exclusively within the MVC framework. Understanding (thanks Dan) that I could and should maintain these objects elsewhere and utilise them in the MVC framework was the leap I had missed (looks simple in retrospect!). So here's what I have ended up with in pseuso code: Code: class Transaction_object This allows flexible arrangements of the transaction header and details without coupling too tightly, and the extended classes allow good precision in terms of the object properties and methods i.e. I can really lock these down. I chose not to implement as CI libraries in the end as the loader.php calls the constructor on load, which wasn't appropriate in all cases. Usage of a require_once where I want to use the objects works well however. Thanks again to all for the help Best regards Paul Populating an array of objects using CI's load->model() functionality - El Forum - 08-02-2010 [eluser]tunesmith[/eluser] If you instantiate objects from a library, but the library calls the model's db routines, then doesn't the library have to have a CI instance as an instance var? So wouldn't instantiating multiple library objects be just as inefficient as instantiated multiple model objects? I suppose it's possible to have it both ways by doing get_instance not in the constructor, but in every function that needs it... |