Search code examples
ruby-on-railsrubyrails-routing

How to hide :id in rails url?


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?


Solution

  • You have a set of possible solutions:

    1. 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

    2. 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.

    3. 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.

    4. 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.