我正在尝试使用base36在第一个回答here之后对rails app的模型ID进行编码 但我不确定我需要做什么。
我在哪里放id.to_s(36)
?我是否需要在数据库中添加一列?
我希望我的网址为domain.com/user/rD4g35tQ
而不是domain.com/user/3
。
Ruby 1.9.3 Rails 3.2.16
这是我在我的控制器中的show动作:
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
答案 0 :(得分:3)
to_param就是为了这个。路由使用它来生成路径。默认情况下,它返回一个对象的id,但您可以在模型中将其覆盖为您想要的任何内容:
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
答案 1 :(得分:0)
是的,我会在users表中创建一个唯一的列,例如'uuid',以存储编码的字符串并用它来查询用户。
在config / routes.rb
中resources :users
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
实际上,使用编码字符串而不是id的原因是出于安全考虑。我建议不要为此目的使用base36编码。您可以使用随机字符串并在创建用户时分配它,例如:
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
<强>更新强>
自定义路线的缺点是失去_url
和_path
助手,更好的方法是保留resources
创建的原始路线并使用Tim的答案覆盖{ {1}}。