Reputation: 20116
I have an atypical Rails application that needs a table to be indexed by a composite key of two values. Which is the correct way using a RESTful service to add a composite key of two values?
If possible, please point to references.
Upvotes: 10
Views: 2918
Reputation: 38772
It took to me a lot of tests to come up with an almost "elegant" solution:
scope "/users/:key1/:key2" do
resource :users, :path => "" do
resources :posts
end
end
It produces:
users_posts GET /users/:key1/:key2/posts(.:format) posts#index
POST /users/:key1/:key2/posts(.:format) posts#create
new_users_post GET /users/:key1/:key2/posts/new(.:format) posts#new
edit_users_post GET /users/:key1/:key2/posts/:id/edit(.:format) posts#edit
users_post GET /users/:key1/:key2/posts/:id(.:format) posts#show
PUT /users/:key1/:key2/posts/:id(.:format) posts#update
DELETE /users/:key1/:key2/posts/:id(.:format) posts#destroy
users POST /users/:key1/:key2(.:format) users#create
new_users GET /users/:key1/:key2/new(.:format) users#new
edit_users GET /users/:key1/:key2/edit(.:format) users#edit
GET /users/:key1/:key2(.:format) users#show
PUT /users/:key1/:key2(.:format) users#update
DELETE /users/:key1/:key2(.:format) users#destroy
Upvotes: 4
Reputation: 13600
Well it's hard to say but the use of a route like this should be fair and good enough.
http://domain/object/:value1/:value2
If both keys can be viewed by the user it's by far the easiest way to do it. If both values are necessary to get the object then it's a good way to do it. If only one value is needed, you could have the main id such as
http://domain/object/:id?value2=...
Or something like this
http://domain/object/:value1/:value2
Where value2 is an optional parameter.
That said, everything else should work as it worked with everything else. The only difference is that routes will have more than just an id.
Also, I have to say that people often misunderstand rest. Rails is heavily using CRUD request and anything can be quite restful. The idea is to have an url that represent what you're trying to access.
Check this out:
https://en.wikipedia.org/wiki/Representational_state_transfer
Don't fear using get parameters if they are needed. The main idea is to have an url that points to a resource and other parameters could be used to get particular things.
I think that in the end the real solution to you question here is common sense!
Upvotes: 1
Reputation: 8638
you can use the gem composite primary keys
, see homepage.
It uses standard RESTful routes and combines the value of multiple attributes in one :id
parameter.
This seems to be a good appraoch, as you still reference the object with its identfier, which is a combination of several attributes in your case.
You may also use this technique without the gem by combining the attributes in to_param
and split then again for searching. It keeps the standard RESTful routes.
Upvotes: 3