Кодировать идентификатор модели рельсов в URL с помощью base36
Я пытаюсь закодировать идентификатор модели для приложения rails, используя base36 после первого ответа, но я не уверен, что мне нужно делать.
Куда я положу id.to_s(36)
? Нужно ли добавлять столбец в мою базу данных?
Я хотел бы, чтобы мои URL были domain.com/user/rD4g35tQ
вместо domain.com/user/3
,
Ruby 1.9.3 Rails 3.2.16
Вот мое шоу-действие в моем контроллере:
def show
@user = User.find(params[:id])
end
Изменить: вот мое действие создать:
def create
@user = User.new(params[:user])
if @user.save
sign_in @user
redirect_to @user
else
render 'new'
end
end
2 ответа
to_param для этого. Он используется маршрутизацией для генерации путей. По умолчанию он возвращает идентификатор объекта, но вы можете переопределить его в модели так, как вам будет угодно:
class User < ActiveRecord::Base
def to_param
id.to_s(36)
end
end
В контроллерах params[:id] теперь будет той строкой, которую вы хотели, но вам нужно преобразовать обратно в реальный первичный ключ:
def show
@user = User.find(params[:id].to_i(36))
end
Да, я бы создал уникальный столбец, например, 'uuid', в таблице пользователей, чтобы сохранить закодированную строку и запросить ее у пользователя.
в конфиге /ways.rb
resources :users
в приложении / 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
На самом деле причина использования закодированной строки вместо идентификатора связана с соображениями безопасности. Я предлагаю не использовать для этой цели кодировку base36. Вы можете использовать случайную строку и назначить ее при создании пользователя, например:
в приложении /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
ОБНОВИТЬ:
Недостатком индивидуального маршрута является потеря _url
а также _path
помощники, лучший способ - сохранить оригинальные маршруты, созданные resources
и использовать ответ Тима, чтобы переопределить to_param
,