0

It's easy to pass a parameter to a controller, as shown here:

root :to => "pages#show", :id => 3

My question is how can the controller ensure this is set programmatically, ie guard against a user manually setting the parameter? Or is there any other mechanism which would let a matching route pass data across to the controller.

mahemoff
  • 44,526
  • 36
  • 160
  • 222

1 Answers1

1

There isn't a way to prevent a user from manually editing the URL. The few ways around it the id being editable that I have used when the situation warrants it:

  1. Use Ajax requests to load the item so the id is hidden from the user
  2. Use something like friendly_id for your model so the id is a slug which is tough to spoof
  3. Do something to obfuscate the URL like the example I put in this question. The gist of it, is you add a new field called url_code and auto-generate one per row in your model and use that as your #id for your route. (Keeping examples below the same model as other example for sake of time, see context over there).

model

Page < ActiveRecord::Base
 validates :url_code, :uniqueness => true
  after_initialize :create_url_code

  def create_url_code
self.url_code=SecureRandom.hex(4) if self.url_code.nil?
  end
end

in controller:

  @page = Page.find_by_url_code(params[:id])
Community
  • 1
  • 1
creativereason
  • 1,524
  • 1
  • 11
  • 20
  • Thanks for the workarounds, but tbh I'd rather just make a new route instead of relying on being unguessable/obfuscated. – mahemoff Jun 04 '15 at 23:55
  • well, using #1 (ajax) can satisfy your concern that a user didn't enter it (because you can restrict to JSON requests) but if you do standard routes you can't change because it's default browser request behavior (in url bar) – creativereason Jun 04 '15 at 23:58