I need to refer to a controller method from a cache observer, How can I make it?
If you need to do it, then something goes wrong with architecture. It breaks MVC pattern because observers bind to models, and we should call model methods from controller and not vice-versa.
an observer binds to models, at least you can write some custom code in lib, then reuse it in obsever. by the way it may depend from what you're doing
Related
I am new to Microsoft ASP.NET MVC framework. I am working on MVC project where I have a controller. It has various ActionResult methods. Also, it needs several helper functions. Can I write them in controller itself? Please guide me.
No, it's not best practice.As helper function needs to be define/implemented in static class. So it is better to to have standalone seprate helper class.
The answer is: it depends. First of all it is not clear what do you mean with helper functions.
if you are talking about ASP.NET MVC HTML Helpers, it is better to move them to separate class. Tutorial how to create and use them.
if you are talking about general helper functions that evaluate something, of course you may leave them in controller, move to the base controller or move to separate class or library (depeneds on context). You may check implementation of standard System.Web.Mvc.Controller, there are a lot of methods and properties in it.
I think there's no specific rule regarding this.
IF
you're going to reuse the helper function, abstract/separate it to another class.
ELSE
put it in the same class for better code cohesion and readability.
I have almost all of the "shared" statements in functions in my model. The problem is that I am getting the following error, when I need to use more then one of these functions in my controller:
Controller action should call one model method other than an initial
find or new
and the IDE goes deeper explaining that:
This inspection warns if a controller action contains more than one
model method call, after the initial .find or .new. It’s recommended
that you implement all business logic inside the model class, and use
a single method to access it.
Is this mean that all of the logic should be put in more complex model functions? I have thought that the work of the controller is to call model functions and passes the results to the view.
If I put back the model functions code back to the controller, everything will work, but I will get a code duplication in all my controller actions.
So, what is the right approach here?
The warning message indeed means that the logic should be put in a single model function, but not necessarily more complex ones. To avoid model duplication and/or the "fat model" problem, you may need to introduce additional classes that the model relies on.
Yes, the work of the control is to call model functions, but only as a thin veneer, per this inspection guideline of one model function per controller action aside from an initial create/find.
I'm not sure I understand your comment about getting code duplication in your controller if you move functions back up, since you can always introduce shared functions at the controller level. But again, that's not the recommended approach of "thin controller" and "reasonably thin model" with supporting classes as required.
I have a GridDataController class that handles all of my data requests from my jqGrids.
I think my application would be easier to maintain if I busted that class apart, put the relevent actions in their respective controllers, keep the grid specific functions in a base controller class and then inherit from that class when I need to retrieve grid data in my controllers.
It doesn't seem right for the Base Controller class to reside in the Controllers folder as I do not want any of it's actions to be called.
Is there a convention for this?
No conventions. It would be easier for everybody though if you put it under Controllers, since its a controller, want it or not :). However, you can put it anywhere and refer to it inside your controllers by using and by inheriting from it (if that's what you want to do).
If you don't want its actions to be called, declare it appropriately as abstract class ...
So, no right answer to your question, but before putting it anywhere, thing twice and change your mind and put it back into Controllers :)
i want to overwrite a method of
symfony/lib/plugins/sfDoctrinePlugin/lib/form/sfFormDoctrine.class.php.
I think a good way could be writing again the method in the form class
where i need that method.
In that case if i need that method in other form class should i write
again the new method, so i would break the rule DRY...
So is there any better way?
Regards
Javi
You should be using BaseFormDoctrine if this is a Doctrine specific method or BaseForm if you want the method to apply to all forms. These form classes are provided specifically for this purpose.
Piggybacking on Colonel Sponz's answer, I've done this many times by extending the class I want to override. By extending the class, you don't have to duplicate anything. In the method(s) you want to customize, just add your customized code and then call parent::method_name() to execute the same method of the super class. You get all the benefits of both. Calls to methods that don't exist in the subclass will execute against the super class.
It should be noted that this strategy is basic OOP stuff and isn't limited to Symfony or even PHP.
You could create a new class that inherits from sfFormDoctrine that redeclares the methods you need and then use your new class in place of sfFormDoctrine wherever you need that method.
I defined a helper abc() in annotations_helper.rb. What do I have to do such that I can use this method in annotations_controller.rb?
In general helpers are supposed to be "view helpers" and not called from controllers.
You probably want to put something like that in application_controller.rb
This is usually not a good practice to use a helper in your controllers. You should try to move the logic inside a model or if the logic is too generic, you should move that to lib/some_lib.rb and include that in your model to use.
However check out this blog post if you really want to do this. Don't forget to read the comments.