fotanus
fotanus

Reputation: 20116

Rails RESTful routes with a composite key

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

Answers (3)

fguillen
fguillen

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

Loïc Faure-Lacroix
Loïc Faure-Lacroix

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.

more

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

Martin M
Martin M

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

Related Questions