Why is $uses considered bad practice in cakePHP?
Asked Answered
C

3

0

I have 3 tables that contain user information, one for students, one for teachers and one for administrators.

They are not related in any way. I wan't to create a dashboard for the Administrators, where a list of students and teachers shows up.

The only way I found to achieve this was using the $uses variable in the Administrators controller. However, I have read in many places that this is bad practice.

Any solutions?

Crenation answered 31/7, 2011 at 2:54 Comment(0)
B
3

Another, perhaps better practice is the use of ClassRegistry::init('MyModel')->myMethod() (more reading @ Cake API)

This only loads the object when it's used, as opposed to loadModel or uses, with ClassRegistry the models are treated as singletons.

--

that you are doing something wrong: you need access to a model that has nothing to do with your current controller.

There are plenty of conditions where you would need to access all of your models data, from one controller, but never a definitive answer on how to do it without breaking convention!

Breadstuff answered 31/7, 2011 at 10:56 Comment(1)
Not a better practice.. here it is from the horse's mouth: groups.google.com/forum/#!msg/cake-php/E3xXtOsBAxc/mMfAOBBFTHkJRyter
R
2

You can always use another Model which is not related by using

    $this->loadModel('NewModelName');

Then you can access new loaded model by:

    $this->NewModelName->add();    // whatever method model has defined

Why prefer loadModel() over uses?

To gain performance. How? uses calls the loadModel function itself to load all the models you specify in uses array. But the problem is if only one of your action needs a particular model, whats the good thing to include it in every action. e.g. only add() action requires an unrelated model, but if you have specified it in uses array, no matter what action gets called a completely unrelated model is going to load. To put simply it will be inefficient. Its like you have declared variables in a C programme but never used them. In case of C compiler will warn you that you are not using your variables, but unfortunately cake couldn't tell you.

Its alright to use uses if all your actions needs to load that model, use loadModel() otherwise.

Rheingold answered 31/7, 2011 at 3:3 Comment(4)
what is the difference between this and the $uses method?Crenation
well internally uses call the loadModel() function itself. every model you specify in uses array loads while instantiating a new controller object. So models specified with uses will be available throughout the controller. It is wise to load them when necessary so use loadModel in favour of usesRheingold
I'm not sure that splattering a series of $this->loadModel() in your controller actions is a wise idea unless you know for certain that you will only ever need the model for that one specific function. Once you duplicate that line of code are you really gaining anything? If you keep unneeded models out of the $uses array and only list those that you truly need would be a much better solution. Easier for other people to maintain as well, they can see it right up front instead of digging through all your controller actions.Gertrudgertruda
the best practice is use cake's association like like $this->Model1->RelatedModel->action(), if models are completely unrelated use loadModel and always avoid uses.Rheingold
S
1

You probably didn't read my answer in your other question :))

I have 3 tables that contain user information, one for students, one for teachers and one for administrators. They are not related in any way. I wan't to create a dashboard for the Administrators, where a list of students and teachers shows up.

The problem is you are separating similar data into 3 different tables, in this case, user information. So when you try to manage this data, you hit a brick wall: because you leave out the relationships when you separate them in 3 tables.

The only way I found to achieve this was using the $uses variable in the Administrators controller.

You got the wrong idea about the controller. Each controller manage the data flow of a particular model (and related models). It doesn't mean that you have to stay in Admin controller to do administrative things. What model you want to manipulate decides what controller you need to be in.

However, I have read in many places that this is bad practice.

Now for the main question: using $uses is a red flag that you are doing something wrong: you need access to a model that has nothing to do with your current controller. Now, there're always exceptions in programming, sometimes we need to have access to that model. That's where loadModel comes in. Because it should be rare. If you need the model a lot, then you'll need to call loadModel a lot, which is cumbersome, which is what $uses is for, but then that means something's wrong with your app design :))

So, you can say using $uses is a sign of bad decision (in DB design or application structure); and so is using loadModel a lot.

Edit: Any solutions? I gave one solution in your other question. But if you want to have them all in one place, you can have 1 users table with user information. Each User can hasOne Student, Teacher, Administrator and a 'group' field to decide what group the User is. The third solution is using $uses. Its performance impact won't be a problem really. But it will be pretty convoluted when you develop your app further. That's what you need to worry about. For example, I can say that, if you use Auth, you'll need to tweak it a fair bit to get it working with 3 models. If you use the users table, it will be a lot easier.

Suffice answered 31/7, 2011 at 6:49 Comment(2)
So you're saying to have a single users table, and then a students, teacher and admin table that will basically just have an id column and a user_id column? Would you rather keep the current design, create admin actions in students and teachers controllers, and then use ajax to get it all in a single page?Crenation
Yes for the first question. For the 2nd: if you keep the current design, use $uses in admin controller is the simplest way (don't worry about the performance impact). I'm not in your shoes to know what's best in the long run, and all of the solutions are in the acceptable range; so just pick one that you feel like using.Suffice

© 2022 - 2024 — McMap. All rights reserved.