Grails: reusing an action - grails

I'm building an application that among other things allows users to upload documents. I have the basic create/view actions working just fine, but i'd like to reuse this action in other places.
I want to know if anyone has a pointer for how to do this. There doesn't seem to be a very good way of doing this.
Here are a few ways i've considered:
Try to do a chain(). This doesn't work since chaining does a GET, and to upload you need a POST.
Break out the main business logic into the Grails "service", and make two actions that use the same code.
Use a JS modal window. I've been thinking a modal that contains an iframe to an "unskinned" version of the document upload. The trick here is to get the window to close when the upload is done.
Thanks
--Matthias

I don't care for the extending controller method. In fact, I avoid inheritance when possible. I'd rather put the common code in a service class and reuse it that way.

You can use a base controller class, and place the common functionality there. Then extend the base controller and call the method from other action methods.

Related

When and when aren't controllers necessary in grails applications?

From what I understand, grails applications with the angular profile don't technically need controllers as the domains support the http requests. So, what exactly is the point of the controller class in these grails applications?
Here is an example I am working on:
I have a Wardrobe class, and a Color Class. Wardrobes have colors, and I want the functionality to add and delete colors from specific wardrobes. However, colors may be a part of many different wardrobes.
I understand I can just add a color to a wardrobe without the controller class, by calling a post request to my 'localhost:8080/color' specifying the wardrobe. Can I also delete a color from a wardrobe with the same logic?
If this is true, why do I need a controller class? In this tutorial, I notice they leave the controller class out. https://www.djamware.com/post/5a10b5f580aca75eadc12d6c/grails-3-angular-5-profile-crud-web-application-example
Just wondering what exactly is the point of having a controller class when working with angular, and when it can be avoided and when it is needed.
Thanks
From what I understand, grails applications with the angular profile
don't technically need controllers as the domains support the http
requests.
That is not the case. We do not support routing requests to a domain class.
In this tutorial, I notice they leave the controller class out.
https://www.djamware.com/post/5a10b5f580aca75eadc12d6c/grails-3-angular-5-profile-crud-web-application-example
It is not really true that they left the controller out. There is a controller there, there just isn't source code for it because there doesn't need to be. The #Resource(uri='/customer') annotation on the Customer classes causes CustomerController to be created at compile time.
Just wondering what exactly is the point of having a controller class
when working with angular, and when it can be avoided and when it is
needed.
When working with Angular (or anything else that wants to send a request to the Grails app), a controller is generally the thing that will receive the request and decide what to do.

ASP.NET Mvc - AutoMapper Best Practice - Performance

I've not looked at the AutoMapper source code yet but was just about to make some changes to an API controller in my solution and had a thought.
The way I like to code is to keep my controller methods as concise as possible, for for instances I make use of a generic Exception attribute to handle try{}catch{} scenarios.
So only the code that is absolutely relevant to the controller action is actually in the action method.
So I just arrived at a situation where I need to create an AutoMapper map for a method. I was initially thinking that I would add this (as I have done previously) to the controller constructor so its available immediately.
However, as the controller grows following this pattern may introduce a lot unnecessary AutoMapper work depending on the controller action method which is invoked.
Considering controllers are created and destroyed per request this could get expensive.
What are some recommendations around this? Considering AutoMapper is accessed statically I was wondering if it's internals live beyond the request lifetime and it internally checks for an existing map before creating a new one each time CreateMap() is invoked?
You should create your maps (CreateMap) once per AppDomain, ideally when this domain starts (Application_Start).

asp.net mvc is it proper to create an instance of a controller in another controller's constructor?

i have several controllers which will all be using common functionality. So i have separated that functionality into a separate controller.
the shared controller needs a parameter specific to which controller it is being used from, and needs to return views based on id ints passed to it.
So, one idea is to create an instance of SharedController(int callingControllerId) in the constructor of each of the controllers that will be using it. Then, within the action methods of each controller, call the action methods of the shared controller, passing appropriate ids, and returning views from SharedController to the calling controller, which would return the view to be rendered.
Does this sound right? Should controllers be creating other controllers in MVC?
Thanks!
Absolutely not although having your controller inherit from a shared, base controller is pretty common.
public KittyController : MySharedBaseController
{
}
Like Greg Roberts points out that although having a ControllerBase is common it is not always the best place to store shared functionality. MVC has a lot of extensibility points and picking a narrow place to wedge in your code is a lot better than smushing tons of things into a base controller.
I would agree that a base controller is pretty common, but I'm not sure it's the right solution for what you are describing.
Without knowing what is exactly shared it's a bit hard to figure out, but the whole bit of your base controller knowing specifics about the controllers that are inheriting from it smells a bit.
Here are a couple things to consider.
Composition is almost always better than inheritance. Great article on this
Base controller should have common methods/properties, for example mine have some properties of getting the current user and a generic method for calling external services, but not specific things from inheriting controllers. Rule of thumb, if it's not needed by more than 1 controller, than probably not good in base implementation.
It's possible that some of the new MVC 2 features might solve what you are doing. Look at render action.
As with anything in software, there are tons of ways to solve the problem, so ultimately do it the way that makes the most sense to you and your team.
Controllers are constructed by the ASP.NET MVC runtime and you should never be constructing them in your own code. It sounds like you don't really need a separate controller, you just need another class that you aggregate in the controller, and use as a service. This is perfectly acceptable. In fact, I would go so far as to say that in general controller should be delegating their work to other "service" classes and shouldn't have much responsibility (especially domain logic) in and of themselves.
I don't know the details of why this service class needs to know what controller it is being called from, but perhaps you can just declare an enum that defines the different use cases, and pass that in in its constructor. Actually having the service class know about different controllers would be a code smell for me.

Rails: How do I keep a complex app RESTful?

I always try to make my applications as RESTful as possible but I've recently begun working on a complex project that requires multiple additional methods in my controller.
I normally achieve this by adding another :collection to the route but it seems like a workaround and in on scenario I have 5.
Are there any best practices for handling the extra methods in a controller? They are generally simple forms that updates a model.
The other solution, which is what I do, is every time you find yourself creating an action that doesn't fit into the RESTful actions, eg Search, so you might find yourself making a search action on an Article controller, what you could do instead of creating this action is create a Search controller instead, and use RESTful actions inside of that instead. There is no rule saying you need to use all the actions, you might only need one or two, but it keeps your API RESTful and your code organised.
This is not a hard and fast rule, but I have certainly found it helpful when I try to decide where to put stuff.
I think there's a bit of confusion in the Rails community about how and where to use the word "RESTful". Strictly speaking, the only thing that can be RESTful is your web API (as railsninja already mentioned). That the code of an application that conforms to the REST conventions (the application with REST API) can usually be organized into a set of controllers (that match the resources) and methods in these controllers (that match the four verbs of the HTTP protocol) is nothing but a hint of how to keep your application clean and organized.
If we want to talk about a RESTful Rails application, we can't just talk about RESTful controllers - there's nothing RESTful about just controllers themselves. It's possible to have a complex web application with only one controller (and myriad of methods) that represents many resources and is perfectly RESTful.
That said, it's pretty OK to add more methods to your controller. Sometimes, it's good to extract some of these extra methods and create a completely new controller - make this any time you feel good about it (rule of a thumb: create new controller anytime you are able to identify it with some self-sufficient resource, ie. a resource which could exist just by itself). Sometimes though, it'd be silly to extract some resource to a different controller. Say you have a resource which has a status attribute. It makes sense to perceive this status attribute as a resource by itself and perform at least one action on it (update), but it won't make any good to extract it to a different controller.
There is a Railscast about this topic, adding custom actions to an otherwise RESTful controller.
Edit: I see that you've mentioned the method in the Railscast as a workaround already. :-) I believe the only other "pure" way to handle it would be to add additional controllers as required to support the actions you want.
"I normally achieve this by adding another :collection to the route but it seems like a workaround and in on scenario I have 5. "
This sounds perfectly fine to me. REST is not about the crud operations and your concern seems to stem from the fact that you are doing more than the basic crud operations but there's nothing wrong with that.

Is there a way to run a view inside a partial

I know this is odd. but I can't figure other ways to do what I need.
I have a controller: report and a view: report.
Also I have a view that acts as a dashboard where I can see several zones (partials).
I need to add this report view to my dashboard but don't know how.
This report view utilizes complex logic from controller and displays the results.
How could I "stuck" the (logic+presentation) of exising view (report) into my partial, so I could use it on my dashboard??
Thank you.
Valve.
(I hope I'm understanding the problem, here...)
This part seemed significant:
This report view utilizes complex
logic from controller
As a general rule, controllers should be simple. Really simple. The rule of thumb is "thin controller, fat model" (Rails Envy made some entertaining but useful screencasts on the subject)
What would happen if you created a new model (quite possibly not inheriting from ActiveRecord::Base) that encapsulated the logic you want to deliver into the partial? Then different controller/action combinations can deliver the information into your views as necessary/required.
Or have I completely missed the point (not impossible!)
I had a similar problem a while ago, when they deprecated render_controller. The only solution I found then was to use ajax, passing a parameter to the page you want to load that bypasses the layout.
If I'm not mistaken you can do a render_component, but this is completely frowned upon nowadays.
This is the easiest way to your problem though
I would suggest to refactor the code from the report controller (if this is the one that contains the "complex" logic) and put it into a wrapper class that can be used by the dashboard and report view.

Resources