I have these nested routes, and I want to hide the id
param from the url.
resources :shares, only: [:index, :create, :update] do
resource :wizard, path: "trade" do
get :first_object
get :second_object
get :confirmation
post :validate_step
end
end
Each page has a form_for
that looks like this up top:
<%= form_for [@object, @trade_wizard], as: :trade_wizard, url: validate_step_share_wizard_path(@object) do |f| %>
So the user adds the first_object
to the wizard, and gets redirected to the following url: /shares/113/trade/second_object
. After adding second_object
(which is obviously different from the first), the user is redirected to to /shares/106/trade/confirmation
. I'm not sure if this represents a potential security violation, and my tests seem to work just fine, so I'm thinking it should be ok if I find some way to hide that id part of the url?
Or is my use case for nested routes incorrect?
You have a set of possible solutions:
As mentioned, you can convert the IDs into something like a slug, or something else, which is what the other answer has mentioned: https://github.com/norman/friendly_id
You can store the IDs of the selected objects in session cookies. That way, the client is still sending the relevant data, but it doesn't really appear in the URL.
You can have an ephemeral Transaction
table, where you can store the first object and the second object. That way, the routes will deal with the transaction_id, while the first_object_id and second_object_id are abstracted away within the table. This will also allow you to store other metadata related to the transaction or the trade process.
You can create a separate endpoint not linked with the shares
controller, where you can accept two (optional) query params: /sharetransaction/trade?first_object_id=113&second_object_id=106
. That way, the URL reflects what is actually happening, rather than changing IDs in the middle for no discernible reason.
The approach you go for depends on your use-case.