views:

80

answers:

2

hi all. I'm developing my latest rails app using a REST style. I've hit a bit of a problem with context however. Let's say I have an Item model. I'm using edit/update to handle the processing, but the model is edited differently depending on the context.

sometimes all I'm doing is changing a 'status' attribute and don't need to show the entire form. In other cases I could be editing associated objects along with the main objects, and then there are user permissions to consider. Some user can edit some of the attributes and others can't. Even confirmation messages stored in flash after a successful update vary.

All these operations are essentially an edit/update but the different contexts make it more complicated. For now I'm using separate actions for each type of update so for example, changing the status is handled by /items/mark_as_sold. Another way I could do this is to have a url parameter in the call to edit or update and process the request differently depending on the context but this gets messy.

How do other developers handle these situations? Is there a 'rails way' to do it?

thanks ev

A: 

I am no expert on Rails or Rest by any means. But I would presume following guidelines while coding myself.

  1. Treat everything as resource and adhere to rest style of modifications/view on resource. So that means show gets one the record to show, index will get all, a post will create new, put will edit and delete will destroy.
  2. As far as view is concerned about whether whole form needs to be displayed or not; it's a view responsibility. In strict sense, a controller's job is to route to right model and back to right view. Any other logic apart from the format to render and some other trivial stuff; would not belong to controller.
  3. If you were to decide whether whole form is to be displayed or only one field; then that decision should be taken up by your view. (JS could play a big role there as with jquery and likes being used comprehensively; it's possible to have stronger control on client side over your view). controller would probably call update_attributes on model and that would give you flexibility in terms of how many attributes you want to update.
  4. Permission logic should be restricted to model and based on permission, only selective data should be served.

I have a specific approach that I like in all my web apps. As long as possible JSON should be used between views and controllers. This has two fold advantage; it very well decouples the role of view and controller and saves any un-intentional overlapping. It lets you expose your controllers as APIs to whole world and re-use them efficiently. (apart from some permission/access related filtering that may be req.)

  1. Associated resources can be updated with nested REST style of updates. I like that particular style but like to keep the depth of resource shallow.

Even a single flag can be updated with same REST action of update just that you call update_attributes method. you really need not put everything as a parameter in URL.

I just believe, that to use the rail's architecture to it's max potential; you just have to have the right design in place and it's always one way or other possible to stay within REST paradigm and rails conventions.

If you could provide any piece of code; where you feel that they will be violated; then please share and maybe we all can suggest improvements in design.

Cheers

Priyank
A: 

About managing permissions: You can segregate your controller into multiple controllers depending on the permissions. This can be done by using the guides post at http://icebergist.com/posts/restful-admin-namespaced-controller-using-scaffolding. About taking decision on context: Once you have splitted your controller into two/more depending on permissions, you can assume that all users of a role are routed to the right version of the controller action. So, it shouldn't be a problem if you use the same update method for updating the whole model or just a few attributes.

Sohan