0

Possible Duplicate:
Ruby on Rails Callback, what is difference between :before_save and :before_create?

I'm looking to replace Ruby on Rails current id from /1, /2, /3, etc to a randomly generated URL, for example /csd8dsv68dvs.

After looking into creating it, I found this in the post model

before_create { self.code = SecureRandom.hex(5) }

What does the before_create do and how can I implement the random id?

Update

It seems I got one part wrong. I'm not looking to change the ID, I just want to change the URL to a random string that a user won't be able to guess.

Community
  • 1
  • 1
user1658756
  • 1,014
  • 5
  • 13
  • 27
  • It is a duplicate but that's not the only thing he/she is asking. Notice he/she needs to know how to replace the default id rails generate with a random one. – Leo Correa Dec 05 '12 at 21:45
  • Definitely take a look at the callback API: http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html – John Naegle Dec 05 '12 at 21:50

3 Answers3

3

A great gem to help you with alternatives to a resource :id as the identfier through a route is friendly_id. There is even a RailsCast on it.

before_create is an ActiveRecord callback and is well explained both here on SO (as others have commented) and in the API.

If you chose to use the raw

before_create { self.code = SecureRandom.hex(5) }

You could modify your controller action to find the resource using this code instead of the id.

def some_action
  @resource = ModelClass.find_by_code!(params[:id])
end

You'd pass the :code attribute to routes for the resource in your views

resource_path(@resource.code)

where resource_path is the route method for your resource.

deefour
  • 34,974
  • 7
  • 97
  • 90
2

I would strongly advise against replacing the Rails id, but if you mean that you want to change the URL to something less predictable, then you're on the right path.

This is a very similar problem to one solved by creating "pretty URLs" which has been solved many times, for example with the Friendly ID gem. Perhaps you'll want to fork the gem and call it "Unfriendly ID" :-)

Whether the gem works out of the box or not, the method is straightforward -- read the code and learn from the guy who wrote it!

Tom Harrison
  • 13,533
  • 3
  • 49
  • 77
  • I tried the Friendly ID gem although it didn't really help. I see what you mean although this application allows users to create things privately, I'd prefer if the URL was random to stop users from guessing the URLs. – user1658756 Dec 05 '12 at 21:56
  • I am not sure why the gem wouldn't help. I understand the goal -- it's perfectly reasonable, but the value you supply for the field used in the URL is entirely up to you -- `SecureRandom` is fine. – Tom Harrison Dec 05 '12 at 22:19
  • I've just updated the question. – user1658756 Dec 05 '12 at 23:39
0

I agree with the other two posters; you probably don't want to do this, and FriendlyID provides a nice way to work with alternate IDs for records. That said, if you really do want to replace the id, you can just change it:

thing = Thing.new
thing.id = some_random_number_generator()
thing.save!

This was already covered in Overriding id on create in ActiveRecord. Seriously consider not doing it unless you have a good reason.

Community
  • 1
  • 1
Jim Stewart
  • 16,964
  • 5
  • 69
  • 89
  • The reason why is because this applications users to create private documents, so I'd prefer if the URL was random to stop users from guessing the URLs even if I were to make it so other users can't see the documents. – user1658756 Dec 05 '12 at 21:58
  • So to reinforce, you *don't* need to change the actual id, just the URL. Changing the ID would be a huge (and entirely unnecessary) pain. – Tom Harrison Dec 05 '12 at 22:12
  • Yeah, I'd use FriendlyID here (or any other method to generate an alternate ID), and then just remove the route for ID-based lookups entirely, or simply rely on user authentication to prevent viewing based on IDs. Security through obscurity isn't useful here. Auto-incrementing IDs hold no information, and you'll want to block access to them in the controller either way. – Jim Stewart Dec 05 '12 at 22:15
  • Ah yes, I'm just looking to change the URL. – user1658756 Dec 05 '12 at 23:30
  • I've just updated the question. – user1658756 Dec 05 '12 at 23:39