Yes, I would create a unique column, for example 'uuid', in the users table to store the encoded string and query a user with it.
in config/routes.rb
resources :users
in app/controllers/users_controller.rb
def show
@user = User.where(uuid: params[:uuid]).first
end
def create
@user = User.new(params[:user])
if @user.save
sign_in @user
redirect_to user_path(@user)
else
redirect_to new_user_path
end
end
Actually, the reason to use an encoded string instead of the id is for the security concern. I suggest not using the base36 encoding for this purpose. You can use a random string and assign it when a user is created, for example:
in app/models/user.rb
class User < ActiveRecord::Base
attr_readonly :uuid
before_validation :gen_uuid, on: :create
validates :uuid, presence: true, uniqueness: true
# ...
def to_param
self.uuid
end
private
def gen_uuid
self.uuid = RandomToken.genf(32)
end
end
UPDATE:
The disadvantage of a customized route is to lose the _url
and _path
helpers, the better way is to keep the original routes created by resources
and use Tim's answer to override the to_param
.