codeigniter model inside a model, and model inside controller - model-view-controller

I have actually 3 questions, but similar to each other:
I have a model called Permissions. and I need another model ie. Users. what is the proper way to user Permissions inside Users.
You get what I mean above, is that weird or is there another better way to do it.
This Permissions model, will be used globally throughout my application, what is the way to use it in other models or controllers (similar with 1st question)

One way is to get the global variable for the main CodeIgniter object, and then load the model from that object rather than $this:
class Permissions extends Model
{
function MyPermissionsFunction()
{
$ci =& get_instance();
$ci->load->model('users');
$ci->users->MyUserFunction();
}
}
You can also sidestep the issue by combining your models together into one larger model. The main reason to keep them separate is to only load the models that you need; if you nearly always use both together (as would make sense, for Users and Permissions), you may be better off taking this approach.

Related

load models in different controller cakephp performance

Suppose I have these models - Post, Category, User. Post belongsTo Category and User.
In my PostsController inside some action I want to get data from categories or users table I can use one of the following
1) public $uses = array('Post', 'Category', 'User') and use Category model like
$this->Category->find('all'); everywhere in that controller
2) $this->Post->Category ->find('all');
3) $this->loadModel('Category '), than use
$this->Category->find('all') in that action
So, my question is which one of these will have the best performance and why ? Maybe for small applications it won't have any visible effect, but what if the project is big and there are dozens of models that should be used in the same controller and every little performance improvement does matter.
Thanks
If you already have the association in the model, use that (#2). This makes sense because these models would most likely already be loaded (if you're not caching).
Otherwise, use the loadModel function. This way you'll be loading the model only when you need it. Either way, unless you have some major work going on in your constructors (you shouldn't), it really won't matter that much.

Access controller method from inside a model

How do I access a controller method from inside a model?
You don't.
Although it is technically possible, if you think that you need to, it suggests a flaw in your application's design.
The Controller layer is the backbone of you application and meant to handle requests from the user, talk to the Model layer, and stitch together the output in the View. Your Model layer should be blind to the Controller and View, but deal with data manipulation only. This is an over-simplified explanation of the MVC pattern (you can find resources for that elsewhere).
Your Codeigniter models should be reusable from any controller, and not dependent on them. There are many solutions to solve whatever problem it is that you have: You can pass data into a model in a number of ways, or you can use the result of a call to a model's method to perform an action in your Controller.
You can use like this:
class some_model extends Model
{
function getController()
{
$controllerInstance = & get_instance();
$controllerData = $controllerInstance->getData();
}
}

MVC - Codeigniter

Where should intermediate code be placed? (something that ins't just storing/retrieving data from DB nor processing requests/views)
For example,
Say I have Listings and I create CRUD functions in the model. These Listings may require more complex tasks such as pausing and resuming, which may require some time calculations, error setting, etc. Should these be placed in the model or should I wrap a simple model in a library and use that as a middleman for the model?
At the moment I'm thinking of using Drivers/Libraries and keeping models rather simple, except for some dynamic SELECT filters. I'm getting a bit confused though, since I'm guessing I'd probably have to recheck variables, dependencies, etc in the model after doing it in the library, yes?
I'd most likely either squish everything together in the model and check once or separate and check twice?
The general rule of thumb is:
1) Perform all business logic in the models.
2) Perform actions like a traffic cop would in controllers. (directing users to new views based on results of activities.)
3) Perform only presentational logic in views.
Anything else that you would like to do that would be considered, "intermediary", could reside in a Library or Helper.
It should be noted though that if you write a Library, don't forget to get an instance of the current CI object in your class so that you have it to use with your internal class methods.
class Your_lib {
$CI =& get_instance();
...
}
Hope that helps.

CodeIgniter $this->load->vars($array)

CodeIgniter has a method $this->load->vars($array) that is ideally used in the parent Controller to provide global access to system variables directly in the view. For example:
$this->data['username'] = "john";
$this->load->vars($this->data);
Then in the view, you can easily access john by echoing $username.
My question is, is it possible to use $this->load->vars($array) from within a Model instead of a Controller? This will allow me to abstract away some details from my Controller, making it cleaner. What changes would I have to make to get this working? Would you recommend it; do you think it breaks MVC?
Also, I'm using Datamapper ORM, so my models actually extend the Datamapper object and not the Model object.
Thanks!
Is it possible to use $this->load->vars($array) from within a Model instead of a Controller?
As mentioned, yes you can do this, you can even load a view from a Model, or even run $this->load->vars() in a view and load yet another view.
This will allow me to abstract away some details from my Controller, making it cleaner.
This is like sweeping the dirt under the rug, it didn't go away - it just went somewhere else where you are bound to deal with it later.
Would you recommend it; do you think it breaks MVC?
It's not going to "break" anything, but it implies that maybe your concept of MVC is somewhat broken. If it has nothing do do with the data layer and everything to do with the view layer, it doesn't belong in the Model. There's a good chance there may be some other stuff that doesn't quite belong there as well...
I'm using Datamapper ORM, so my models actually extend the Datamapper object and not the Model object.
You may need to call get_instance() and assign it to a variable or class property for use in DM models, so you can access the Codeigniter object.
Example: $CI =& get_instance(); $CI->load->vars();
Suggestion:
Return the data from the Model in the simplest, most reusable form possible, and then assign it to the view variables in the Controller. If I'm hunting down the source of some variables in a view file, the last place I'd look for them is in the Model. You may end up revisiting this project in the future, so try to be consistent as much as you can, and stick to the suggested, expected practices.

CodeIgniter Model / Controller and UserID

My Models in CodeIgniter need to check that a user is authorised to perform the given action. Inside the Models I have been referencing using $this->session->userdata['user_id'].
My question is - should I be setting a variable to $this->session->userdata['user_id'] in the Controller and passing this to the Model, or simply checking it inside the Model ?
Does it even matter ? I suppose passing $user_id into the function would make it (slightly) more readable. What are the arguements and recommendations for / against ?
You can choose between data that is fundamental to your application and data that is incidental to a given model member function. Things that you use everywhere should be guaranteed (base members, globals, etc.), and things used only in the current function should be parameters. You'll find that using implied variables (like $this->session->userdata) in many places in your models and views will become spaghetti quickly, and will be unpredictable if you don't bootstrap them properly.
In my CodeIgniter projects, I add a custom base model and controller that inherit from the CI framework, adding their own member data that is used everywhere in the app. I use these base classes to provide data and functions that all of my models and controllers use (including things like userID). In the constructor of my_base_controller, I call the CI base constructor, and set up data that all of my controllers and views need. This guarantees predictable defaults for class data.
Strictly speaking $this->session->userdata['user_id'] belongs to the controller.
Models deal with data only... controllers, by definition control the flow of the data...
and authentication is a form of data control... (IMHO)
Codewise, I follow this procedure
class MyControllerName extends Controller{
function MyMyControllerName(){
parent::Controller();
$this->_user_id=$this->session->userdata['user_id']; //<-- define userid as a property of class
}
}
And then, say one of my functions foo() requires authentication.. I would do this
function foo(){
$this->_checkAuthentication(); //should short out if not authenticated
//rest of the function logic goes here
}
the _checkAuthentication() can be simplistic like:
function _checkAuthentication(){
if(!isset($this->_user_id) && $this->_user_id<=0){ /or any other checks
header("Location: ".base_url()."location_of/user_not_authorised_page");
exit;
}
}

Resources