I'm building a new Rails app for a client and one of the requirements is to allow people to fill out service request forms. There are 10 request forms so far and they're all different. To implement this I was thinking of creating a separate Model, View and Controller for each one to keep everything simplistic and RESTful. I'm kind of worried though about having 10+ different MVCs and routes just for the forms. Is there potentially and better way to achieve this?
Also the data submitted just gets emailed. No saving to a database.
Thanks for any help! :)
You're correct to make them all separate resources, controllers, models, etc.
If possible, you can DRY the code that is similar among them. For example, if some of the forms have similar validations, or parameter filtering, or scopes, etc.
I'm kind of worried though about having 10+ different MVCs and routes just for the forms
In my opinion, 10+ different MVCs are fine for 10+ different resources. You may be interested to read about "DAMP" coding. I personally recommend DRY underpinnings and DAMP resources.
Related
I've read quite a few articles on good design for Rails APIs. However, I can't seem to find what I'm trying to do. And it's different enough that I'm not sure what to do.
So this Rails site has forms for generating various records for my various tables. It all works fine. No problem there. This is all admin-level stuff.
However, a few of these forms need to be also be available as an API. Right now my APIs work fine but it's poor design (I think). Currently the user will make an API request to do some action and pass some information in (i.e. add record to Foo).
My method inside the API, special_new_foo, more or less duplicates my create inside the foo controller that a form would route to. Is there a way I can reuse my standard create method? The API would then just check for good data, etc. and pass the information onto the controller...
I was thinking about just making an HTTP request to the local server on the machine (which is basically how the forms work, except they're two separate machines). Is this good practice?
Thanks!
One option is to allow you controller to respond with different formats, depending on the request. I think this is what rails generates on scaffolding. However i barely saw any real world app doing this. See also my answer to Is it necessary to build a separate API endpoint for mobile apps to access a Rails web app?
A better solution is to make an extra ServiceObject or FormObject dealing with business logic of your controllers and reuse this object in both endpoints
see http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/
I'm developing a rails app, it's a regular site, but I need to develop an API, so I was reading and trying some stuff, the options that I've thought are (others are welcome):
Versioning the API and separate the API from the controller.
Pro: Clean and separate stuff. Cons: the need to handle 2 controllers for the same task.
Not versioning and keep everything in the same controllers, views can be done with jbuilder. Pro: not really easy way to version it. Cons: harder to expose only parts of the app. harder to route stuff like in an versioned way.
I really want to avoid duplication, but I need some way to avoid that, and make some nice routes like in a versioned way, I don't want to have more than 1 controller for some type of object, in a versioned way if you have 3 versions you'll end up with 4 controllers, that is a lot to maintain.
Please correct me if I'm wrong, and hope to get some good answers :)
Thanks.
Versioning your API is the best route to take.
If you have 4 versions, 1 controller, you still only need to maintain 2 controller (the one in the web facing application, and the most recent version of the API.)
If you have write access in your API, you would be able to take advantage of your own API in your application and not need to create a new method in both the API and in the main application (AJAX).
It is possible that your filters are different. You may need different types of authentication for the API and the main application.
The biggest argument for versioning would probably be that if you have anyone other than yourself consuming the API, their application would not break the day you deploy your changes.
Besides, you should keep to the 'thin controllers, fat models' mentality. That would prevent a lot of duplication with that alone.
I always code api within their own namespace because these points could be very different from the main app:
format rules
auth
rescue
versioning
before / after filters
Even if you have duplication in controllers, there should not be much code, and I cant see why it would be a big deal. Actually it could even force you to abstract your code and have thin controllers.
I'm building a website using MVC3, EF, and Razor and I currently have the front-end of the site mostly working. It's a "store" of sorts with products, users, etc and in the front end you can browse for products, see ratings by users, and purchase the products.
Now, I am thinking about the back-end and from what I have so far, it seems like hte back-end will be redundant in a lot of ways. I would like to have an entire back-end area to manage all the products, users, sales, etc (preferably /Admin/Controller/Action, but if I want a page in the back-end that lists all of the products, this is going to be identical (at least from the controller standpoint) to the front-end controller that lists all of the products.
My question is, what are some good ways to go about this, am i completely wrong so far, or am I on the right track and just need some tweaking. I have also read about Areas, but have been unable to find any good documentation to use with MVC3. Should i duplicate functionality in the back end or is there a better way? Thanks for the help!
I believe you're going about this in a good way, but I think you're dead on when you were thinking about putting your Admin in an Area. I tried googling for something from Scott Gu for areas, but surprisingly couldn't find anything dedicated to it, but there is this MSDN article:
Organizing an Application using Areas
I know you're worried about having controllers with similar actions (and maybe similar models) with the admin as well as the frontend, but it's still probably optimal to separate the logic. Don't over-think or over-architect it, because at some point, you may have to modify the admin controller, but not the front-end controller. Models are typically the point that can be commonized between controllers.
To me, this seems to make little sense, but after reading the information in the following:
http://weblogs.asp.net/scottgu/archive/2010/02/05/asp-net-mvc-2-release-candidate-2-now-available.aspx
http://bradwilson.typepad.com/blog/2010/01/input-validation-vs-model-validation-in-aspnet-mvc.html
http://blog.stevensanderson.com/2010/02/19/partial-validation-in-aspnet-mvc-2/#comment-35397( specifically some of the comments)
It appears that the idea behind Asp.Net MVC is that you have a one-to-one relationship between models and views. This seems to go against the DRY principle and several other standard programming practices.
For example, lets say you have a user account model and there are two views available to edit it - one for the user himself to edit it and one for the site admin to edit it. The admin has access to an additional field for something internal, required but the user cannot view/edit it. Per the model binding functionality and the beliefs described in the posts referenced above, I would need to create two separate user models, one for each page, and the only difference would be that additional field. This is just a simple example as well, I've got a few that I've seen where it would potentially mean 5 or 6 different models for the exact same object, just a few fields different between each view. That really doesn't make any sense to me.
I did not read the posts you mentioned, but there is nothing wrong with having one Model for a couple of views.
I would just have this one UserModel and use it in all Views, even if there are some fields that are not used.
If things get a bit more complicated but Users still have a lot in common you can either use aggregation for the usermodel (User.Address) or use Interfaces (User has fields street , and city and implements IAddress).
Both methods have their pros and cons - with aggregation used in the majority of situations.
EDIT
After reading the posts I saw that they deal with validation. This is a different story.
If you want to use DataAnotations you have to have different classes if validation varies. I dont use DataAnnotations - so I guess your class design might be different.
If you're using annotations, I'd strongly consider one "model" and multiple "viewmodels." We went with a viewmodel approach on our current app and have been reaping the benefits, because our basic model needs to be shown in a couple different views.
There is no official requirement to have only one view per model in ASP.NET MVC. In many cases that would lead to duplication of code.
I personally like to split model-view dependencies, that is, one view per model. It comes down to the fact that you never know how, say, a couple of very similar model-view pairs are going to evolve in the future. If they're separate, you just introduce changes in one and you don't have to "fix" the other views that were dependent on this model, or worse, to take extra work to create own models for them all at once.
TL;DR: Make many view models. They are cheap and flexible.
"This seems to go against the DRY principle and several other standard programming practices."
[Citation Needed]?
MVC doesn't change the fact that in any language or pattern you need to make a view model definition for each separate screen. Whether via attributes, via XML, via toggling web form controls, whatever.
The DRY principal usually pertains to repeating business logic. Repeating a FirstName property across a CRUD screen section really isn't a big deal. Even 5-6 times, whats that? 40 seconds?
If you mistake your view models for object oriented classes and not homoiconisticish screen representations you run the risk of filling them up will all sorts of inheritance and or business logic.
Your not really programming when you make dumb view definitions. This work could easily be done in an Access GUI or defined in XML. The fact that your screen-view-models are in C# just makes it easier to fill them up with data and ship them around and work with tools like WCF and Automapper.
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.