Using Preloaded Model Via BaseController in Other Controllers |
Hi Everyone,
I am trying to use and/or extend a model which is loaded in the BaseController's initController() function which uses the RequestInterface. I was using the below to set a variable in initController(). PHP Code: new \App\Models\Base_layout_markup_model( $request ); I wish to use this model globally, and have other models extend from it, so I can call its functions in the other model, however, nothing has come of it. I get errors mentioning I need to set database properties, to references of NULL when calling the base model functions in the class that extends it. The only way I get things to work is using this process:
I also thought the idea of preloading models in the BaseController would make them available globally? Otherwise, each model that I load then has to load the base layout model if I want to use it. What is the best practice of preloading a model in the BaseController, which has access to the RequestInterface, which is available globally in other models?
Quote:I would have thought that since I am extending from that 'base' model, I would not have to instantiate it in the constructor? You don’t need to instantiate it if you extend the class. Show some more code, you’re doing something wrong. I’m not sure what you’re trying to do, but you can load a shared instance of a model with the model() function. You don’t need to load it globally in the base controller in case you need it. Also, the controller already has the request object in $this->request. You don’t need to load it.
CodeIgniter 4 tutorials (EN/FR) - https://includebeer.com
/*** NO support in private message - Use the forum! ***/
Hi, more code.
The intent is to have a model for each controller if really need specific data for that page. The base layout view will be driven by the 'base layout markup' model, where the 'controller specific' models will call its '_base_layout_markup' function. My BaseController: PHP Code: namespace App\Controllers; The site home controller: PHP Code: namespace App\Controllers; The site home model: PHP Code: namespace App\Models; The base layout markup model: PHP Code: namespace App\Models; I am now at the point where I receive Attempt to read property "uri" on null on the following line: Code: $this->_uri_obj = $this->_request->uri; The only way around this is by replacing: Code: $this->_request = $request; Code: $this->_request = \Config\Services::request(); Is that considered a 'best practice'?
(10-10-2021, 11:43 PM)Mr Lister Wrote: I am now at the point where I receive Attempt to read property "uri" on null on the following line: You have this error because you never pass the request object to your model, $request is null: PHP Code: $base_markup = $this->_base_layout_markup(); // nothing is passed for the $request parameter A model is tied to a database table. Yours seemed to be tied to a specific controller, which is weird in my opinion. I’m not sure either why your model need to access the request object. If you follow the MVC pattern, this would be a job for the controller. The models are used for database operation, not dealing with the request and user input.
CodeIgniter 4 tutorials (EN/FR) - https://includebeer.com
/*** NO support in private message - Use the forum! ***/
@includebeer My idea is to have a shared model, (the 'base layout markup'), which will set up the layout view and the renderSection() content is obtained via the specific controller.
When using the extend() function in the content, the layout view inherits the data. The controller calls its model, (which will most likely have a db table), this model will extend the shared 'base layout markup', so has access to its functions to gather the layout view data. Ultimately the 'base layout model' and its associated table will have meta data, HTML title tags etc to create the page, which will be determined by the URI segments, i.e., domain.com/segment-one/segment-two will query the db table for 'segment-one' and 'segment-two' for the page layout. Hence why I need the request service so I can obtain the URI segments. What is the best way to obtain the URI segments in the model? Or should I use the controller to pass $this->request to its model, which then passes it to the 'base layout markup' model? My strategy is to have a db table to contain meta data, HTML tag data to generate the layout view, and then its associated content can be in its own table. This can then be edited / updated etc in an Admin area. Alternatively, all of the page's markup and content will be in one table, (and not use the layout view / renderSection() function), which will be queried using the URI segments, which more or less leaves me with the same issue, obtaining the URI segments. But I would like to separate those concerns; update one layout view rather than have to update it for each view for a controller if it requires update. Hope that makes sense for my thinking :-) I love the idea of Codeigniter allowing developers to do it 'their way' in some respects. However, as you mention, I also wish to stick to the MVC pattern as much as possible.
Change this in your base layout model.
PHP Code: // Change: The request. Try that. What did you Try? What did you Get? What did you Expect?
Joined CodeIgniter Community 2009. ( Skype: insitfx )
Personally I would collect what I need from the request in the controller, and pass this to the model as a parameter. This way the model is not dependent on the incoming request and only deal with database requests. It would also make it easier to test your model if you can just pass an array of options.
But like you said, CI doesn’t force anything and let you do what you want, how you want. So it’s up to you. But I advise to stay as close as possible to the MVC pattern.
CodeIgniter 4 tutorials (EN/FR) - https://includebeer.com
/*** NO support in private message - Use the forum! ***/
@InsiteFX, @includebeer
Thank you for your replies and help. I think I will split the difference in what I will implement. In my BaseController, I will obtain the current url as an object instance via the URL Helper, as it is automatically loaded on every request. PHP Code: $this->_url_request = current_url( true ); I then pass that parameter to the model(s) from the controller. If that is in-keeping with MCV patterns, I am happy to go with it. Thanks again, much appreciated. |
Welcome Guest, Not a member yet? Register Sign In |