I'm trying to use helpers to handle processes that involve multiple models. Is this okay in terms of best practices?
What sort of work is being done in the helpers? A library might be a better choice.
The codeigniter user guide describes helpers:
Helpers, as the name suggests, help you with tasks. Each helper file is simply a collection of functions in a particular category.
Think of them as akin to standard php functions. You can use them anywhere.
If it gives you the creeps to use helpers the way you are, consider your controllers as 'routers'. Use them to send information to a model and receive it back. Then you can send that info somewhere else, like another model. When you have all the info you need, you can use a helper or another function in the same controller to manipulate the information.
Personally, I mostly use helpers in my views to reformat or transform data.
Related
I am using Multiple code blocks of Mail:: and Gate::define() in my code. I rather want to make it as functions and call them. What approach would be useful? Should I create helper classes?
If You have some logic and you want to use this logic from many places, you must to encapsulate it, an in your situation it's not bad solution to create helper function or maybe helper class.
If You don't know how - here is very clear example to do it :
Creating a Helpers File
I have a controller that is starting to feel very bloated. Some of the actions themselves are very large and much as I try to split things up, navigating this file is getting tiresome.
I was wondering if there is any way, and specifically any convention, for managing very large controllers? Is there a way to split a controller up into easier-to-manage sections?
I see that there is a CAction class. Is this the way to go? What about methods that aren't actions?
I think you should read this link http://www.yiiframework.com/doc/guide/1.1/en/basics.best-practices to improve your structure with MVC.
Besides, If you want to make your controller be simple then you can use CAction.
From http://www.yiiframework.com/doc/api/1.1/CAction:
CAction provides a way to divide a complex controller into smaller actions in separate class files.
To make your model be lean, you can use Behaviors from Yii.
Maybe your controller is bloated because it's doing things that should be sent to the model? Controllers should act as traffic cops. They respond to a request, gather the needed data (from various models), and then send that data to a view. Maybe your controller is doing some of the work that your model(s) should be doing?
I have a several functions which are quite large, and are only used in one controller function each, and I'm wondering where to put these? They are not displaying any views, but instead crunching some numbers.
If I'm not wrong, there are 4 possible places where i could put these function: in my controller, in a helper, in a library or in a model. But none of these seem appropriate, since I don't want the code to be loaded every time a user uses the controller, and model should be used to do database stuff, and helpers and libraries should contain code that can be used over and over again.
If it is business logic, the best place to put it is in the controller as a private method, then you can call that method from within the controller.
Just as a note, helpers aren't always loaded unless you autoload them or load them in the constructor of your controller. So, as an alternative, you can make these methods of a helper then just load the helper in the controller action you wish to use them. That way they only get loaded when you need them.
CodeIgniter comes with helpers that you probably might not use (doesn't load unless you specify it in the application/config/config.php file) and I don't think its a problem having functions that you only use once stored there (application/helpers ). For example I might use a random password generator once only, but its still there and won't be loaded unless I call it.
$this->load->helper('my_string_generators');
How do I use a component that I created in cakePHP inside one of my model classes? Is this possible?
If so, please let me know how I can do so
It is possible but pretty bad practice in a MVC framework. You should re-think and re-organize your code if you think you need to use the component in a model because something is cleary wrong then.
A component is thought to share code between controllers, only between controllers.
Components in CakePHP 1.3
Components in CakePHP 2.x
Components in CakePHP 3.x
To share re-usable code between models it would be a behavior. For a view it would be a helper.
If you have some really generic code it should be a lib or put it in the Utility folder / namespace or create a new namespace. Check the existing classes there to get an idea what to put in there.
No code was provided so it is not possible to give any real recommendation on how to refactor it. However the way you want to use the existing code won't work in the MVC context, so time to rethink your approach of whatever you try to do.
It is possible to use a component inside a model (but I cannot comment if this is a recommended or a best-practice).
Inspired from original source, an example to use a component called ‘Geocoder’ in a model:
App::import('Component','GeoCoder');
$gc = new GeoCoderComponent(new ComponentCollection);
Then you can use $gc to call the functions of the component.
--
P.S.: I do not want to encourage bad programming practices, but sometimes the pressure of deadlines (in real world projects) may force a developer to make such decisions.
#AD7six
// Use anywhere
AuthComponent::user('id')
// From inside a controller
$this->Auth->user('id');
From the cake PHP documentation they provide AuthComponent::user('id') so that it can be used in places other than a controller.
Maybe I need a bigger hint, but why shouldn't my model be able to access ACL information ?
I'm writing a Cake component and it seems to make sense that I use it for saving data rather than doing so in a controller. In the manual it says using models in a component is discouraged, but the other way of doing it would mean I'd be repeating code in the controller.
The component basically analyses a load of data from various sources and will then insert data for various models.
If the component analyses a load of data from various sources, it can probably be written as a behaviour.
If not, and you have no other choice but to use a model in your component, be sure to do it properly:
$this->ModelName = ClassRegistry::init('ModelName');
I personally don't see a problem with this, since the core components (such as the Acl component) do that. As long as your component handles the application logic and models handle data, you'll be just fine.
In my opinion, DRY is the critical path. To that end, I see two options:
Instead of saving the data in the component, return it to the controller in a raw form that can be saved from the controller.
Go ahead and import the model into the component and do what you need to do. It's not encouraged, but they do make it reasonably easy.
If it comes down to a hard choice, I'd err on the side of keeping my application DRY rather than maintaining a strict MVC discipline.
One could argue that if you want to write data generated in a component and have the ability to package the component up for distribution it would make sense to load a model in your component(especially if the model is part of your component).
For example I have a authorize.net AIM (credit card authorization) component.
From my controller I call the components charge function.
Authorize.net sends me a response (within the component) and according to DRY I would want to save the data within the component so I don't have to repeat saving the data from wherever the charge function is called.
Another plus to straying away from convention would be the fact that I could use a model from within the component and not have to have a model in the app.
What do you think?
With the versions of Cake I am familiar with (1.3, 2.0), you can requestAction from another controller. This apparently is also bad practice, but they provide the function for obvious reasons. I have used this in some situations but I have had sketchy results when trying to pass data back and forth. I would avoid using this method as well except for simple functions.