Let's assume a generic join table FollowCompany between a User and a Company model, e.g.:
class FollowCompany < ActiveRecord::Base
attr_accessible :user_id, :company_id
belongs_to :user
belongs_to :company
end
It has a composite primary key [user_id, company_id]. It does NOT have an id column since a follow_company record is uniquely identified by [used_id, company_id]
Since I want to be able to treat the following relationship as a resource I made it RESTful:
routes.rb:
resources :follow_companies
This however causes a problem: These generated routes assume an :id key which I don't have. How do I tell rails that I'm actually using a composite key instead?
I can think of four solutions and I would like some input on which one is the best:
Don't make :follow_companies a resource. Instead, match the URLs with a two key pattern: e.g.:
match '/follow_companies/:user_id/:company_id/' => follow_companies#edit
This however is ugly because it's verbose and not RESTful.Override the FollowCompany to_param method to contain both model ids, e.g.
def to_param "#{user_id},#{company_id}" end
This however is ugly because it seems like a hack and it has some nasty side effects
Add a primary key column to the follow_company table. This however is ugly because it adds redundancy. follow_company records are uniquely identified by [company_id, user_id]. No need for an additional key.
Download a composite-key gem and integrate it with my dev environment. This however is ugly because it's not a standard way and not compatible with other ruby code.
So, as you can see I couldn't come up with an elegant solution. This seems like such a common scenario though that I can't be the first one to run into this. Virtually every app makes use of (restful) join tables. What's a best practice of handling this?