map.resources with alternate primary key(s)
-
01-10-2019 - |
Question
I have a Rails model Object
that does not have an ID column. It instead uses a tuple of primary keys from two other models as its primary key, dependency_id
and user_id
.
What I want to do is be able to do something like this in routes.rb
:
map.resources :object, :primary_key => [:dependency_id, :user_id]
And for it to magically generate URLs like this:
/objects/:dependency_id/:user_id
/objects/:dependency_id/:user_id/1
/objects/:dependency_id/:user_id/1/edit
...Except that I just made that up, and there is no such syntax.
Is there a way to customize map.resources
so I can get the RESTful URLs, without having to make custom routes for everything? Or am I just screwed for not following the ID convention?
The :path_prefix
option looks somewhat promising, however I would still need a way to remove the id
part of the URL. And I'd like to still be able to use the path helpers if possible.
Solution
You should override Object
model's method to_param
to reflect your primary key. Something like this:
def to_param
[dependency_id, user_id].join('-')
end
Then when you'll be setting urls for these objects (like object_path(some_object)
) it will automatically gets converted to something like /objects/5-3
. Then in show action you'd have to split the params[:id]
on dash and find object by dependency_id and user_id:
def show
dep_id, u_id = params[:id].split('-').collect(&:to_i)
object = Object.find_by_dependency_id_and_user_id(dep_id, u_id)
end
You can also look at find_by_param
gem for rails.