3

I was wondering if controllers at CakePHP should not contain any private function which is not accessible by URL.

Sometimes some functions such as add or delete can be so large that I prefer to divide them. Should I put that functions inside the model instead of making then private on the Controller?

Thanks.

tereško
  • 58,060
  • 25
  • 98
  • 150
Alvaro
  • 40,778
  • 30
  • 164
  • 336
  • you shoudn't have the need to use private methods. use protected instead. in a framework context it doesnt make sense to make sth private since at some point every class could at some time be extended. but protected methods inside controllers are pretty common. – mark Sep 21 '12 at 21:12

4 Answers4

4

Yeah it's probably for the best if you keep your methods in the Model. Like you yourself have mentioned in the comment, "keep models fat and controllers thin". The controller is just a medium which is supposed to interact between model and view.

The problem comes when you have to deal with changes in datasources, tables. If your controllers are fat, you would have used the fields everywhere, and now you will be left with cleaning the whole setup in places where it wasn't supposed to be.

The added benefit of methods in models is that you can call it from other models and reuse the code. For example:

class User extends AppModel {

     public function getAllActiveUsers() {
         // return active users
     }

} 

The above method can be accessed by every other methods in both model and controller, which is related to the User.

If you need such functions elsewhere and if you don't have them defined in the User model, you will either end up redirecting it to the controller or writing the whole logic all over again.

The redirecting thing isn't that bad but consider what happens if you have rewritten the logic elsewhere, and then your implementation of ActiveUsers changes. You will end up having to correct things everywhere.

However, there are a few things that have to be done in controller. For example, if I have to calculate the distance between the user's geolocation and all the matching restaurants for a nearby distance, I should do this in the controller. But it is in the best interest that the controller is left thin, and components exist for this purpose. You can create your custom components for complex and lengthy logic.

Daniel Causebrook
  • 469
  • 1
  • 8
  • 20
Kishor Kundan
  • 3,135
  • 1
  • 23
  • 30
  • How you distinguish the functions which have to be in the controller from the ones who have to be inside the model? – Alvaro Sep 23 '12 at 16:43
  • Well, everything that probably has to do with records being inserted or taken out will go in the model that includes the pre and post logics related to insertion and extraction. But the things like interpretation/computation of/from data possibly even involving other models is best kept in controllers. "Controllers present the data to View". The control flow methods HAVE TO BE in controllers. things like authentication. Methods that interact with third party like email, other API's or even opening your API. – Kishor Kundan Sep 23 '12 at 17:52
  • So, there's nothing wrong on using private (or protected) functions on the controller which will not be accessible by url. (if they just work with data and not with any model) – Alvaro Sep 24 '12 at 07:22
  • absolutely. you can use private/protected methods on controller at will but if possible do avoid using Data manipulation from them – Kishor Kundan Sep 24 '12 at 11:31
  • For example, a function to check permissions for each function and user group (with no DB queries) could be in the controller? – Alvaro Sep 28 '12 at 11:34
  • 1
    Yes, it can be in controller. If it gets too length and if you have to use it in other controllers, considering creating a component for it. – Kishor Kundan Sep 28 '12 at 15:17
1

I put lower-level functions in the models. Especially if the function can be used by multiple controllers. By "low-level" I mean as close to the model data as possible. If you're going to be doing view-specific modifications to the data or combining it with data from other models (related models are an exception), the function does not belong in the model.

Also, you can just prefix any controller function with an underscore and it won't be available via the url.

Costa
  • 4,851
  • 33
  • 30
1

The logic, that deals with adding and removing entries from database are part of domain business logic. Such methods should be part of the model layer.

Since CakePHP's implementation is extremely limited (it pretends that model layer is collection of active record instance), you might move those methods to some sort of helpers, or use separate "models", which do not inherit from AppModel. Instead such structures would be able to act like services, which isolate controller (and presentation layer as whole) from the domain business logic.

tereško
  • 58,060
  • 25
  • 98
  • 150
-2

No. CakePHP is a framework, feel free to create private functions for reusable bits of logic. It's probably encouraged.

Martin Bean
  • 38,379
  • 25
  • 128
  • 201