Reputation: 2712
Lets say we have a Company model, that has many Employees And has many Projects
If we want to show the projects, we'll go to
"/company/1/projects/index"
If we want to edit 1 project, we'll go to
"/company/1/projects/1/edit"
What if we want to edit all the projects at once on the same webpage?
We can go to "/company/1/edit" and put a nested forms for all the projects
But what if we need a different webpage to edit all the employees at once too?
We can't use "/company/1/edit" again..
Right now we do "/company/1/projects/multiedit", "/company/1/projects/multupdate"- but as you can see, it's not rest.
How can we model this restfully?
Upvotes: 2
Views: 198
Reputation: 26393
How you organise your domain model should not be a major influencer on the GUI design and vice-versa.
What if we want to edit all the projects at once on the same webpage?
Then you probably should provide widgets for each and POST each update sequentially. You can use AJAX to make this a nice experience for the end user
Right now we do "/company/1/projects/multiedit", "/company/1/projects/multupdate"- but as you can see, it's not rest.
And that's fine unless you need to be RESTful - do you? Is your application for external use or for an internal business process?
There's a lot more to REST than organisation of resources - nested or otherwise. You should also be concerned with the navigation from resource representations.
If you really feel that you need to be RESTful and if you believe (as you mention in the comment below) that the state of all projects and employees needs to be atomically updated then you should
1. Introduce new container resources "Employees" and "Projects" to model the association between a Company and a set of "Employee" and between a Company and a set of "Project".
2. In response to a GET on Company you must include URIs for the Employees and Projects resources (i.e. a total of two URIs).
3. In response to a GET on Employees or Projects you should either return the state of all underlying resources or URIs for each so that their state may be determined.
4. When updating the Employees you must resend all of the state of the underlying resources (presumably in one huge ). The new state completely replaces the old state,
That last step is a lot of overhead - you should reconsider the constraint that its an "all or nothing update." Remember that this is nothing to do with REST - what you've done is expose an invariant in your business logic to the service interface.
1. do everything I could to remove that invariant from the presentation layer
2. model the resources in a non-nested way - it's more flexible and REST has nothing to say about URIs except that every resource should have one
3. introduce the Employees and Projects resources to model the association between company and employee and project
4. have the representation of the company return the URIs for the Projects and for the Employees (two again).
5. have each employee and project representation contain a to the relevant company
6. design the UI so that it can display a list of projects / employees for a company and allow each to be updated individually
7. batch all of the POSTs together and send them via AJAX on a common button press
It is worth taking a look at the excellent screencasts that Ryan Bates has made on nested resources but don't forget that nested resources aren't a core part of REST - to quote Roy Fielding
What matters is that every important resource have a URI, therein allowing representations of that resource to be obtained using GET.
Enough said - good luck! Chris
Upvotes: 3
Reputation: 15126
I think the way you are doing it now is pretty good actually. Inventing artificial resources just to fit in with the basic REST URL scheme doesn't seem right to me. Besides, Rails has collection and member routes precisely for the purpose of adding extra actions, so what you're doing is in line with the Rails philosophy.
For me defining resources and actions is similar to designing classes. Sometimes you add a few methods and realise that the design would be better if you divided the class into two, but other times the class just needs to have all those methods.
Do you have a bona fide resource other than companies and projects that should handle multiedit and multiupdate? I think not. But then again, just as with classes, sometimes it's a matter of opinion.
Upvotes: 0
Reputation: 83680
API:
http://apidock.com/rails/ActiveRecord/NestedAttributes/ClassMethods/accepts_nested_attributes_for
Check Rayan Bates Railscasts:
http://railscasts.com/episodes/197-nested-model-form-part-1
http://railscasts.com/episodes/197-nested-model-form-part-2
Upvotes: 0