我有一个使用Ruby On Rails创建的Web应用程序。现在,当我想显示一个对象时,我必须访问以下页面:http://mywebapp.com/object/1234,其中1234是对象的id。
我想对该对象id进行编码并得到以下结果:http://mywebapp.com/object/5k(这只是一个例子)。
怎么做?
非常感谢,
马丁
答案 0 :(得分:5)
所有这些转换方法都是可逆的,所以恕我直言,如果你的对象有一些名称或标题或其他什么,那么最好的方法是添加一个slug。 在这种情况下,向对象添加一个新属性:slug,让它自动从模型上的对象名称(或其他东西)生成它的值:
class MyObject
validates_format_of :slug, :with => /\A[a-z\-0-9]*\Z/
before_validation :generate_slug, :on => :create
def generate_slug
if self.slug.blank?
slug = self.name.mb_chars.downcase.normalize(:kd).to_s.gsub(/-/, " ").squeeze(" ")
slug = slug.gsub(/\s/, "-").gsub(/[^a-z\-0-9]/, "")
current = 1
self.slug = slug
while true
conflicts = MyObject.where("slug = ?", self.slug).count
if conflicts != 0
self.slug = "#{slug}-#{current}"
current += 1
else
break
end
end
end
end
end
然后网址可以是http://mywebapp.com/object/my_object_slug,因为在行动中你可以通过这个slug找到对象:
class MyObjectController
def some_action
my_object = MyObject.find_by_slug(params[:slug])
...
end
end
不要忘记修改routes.rb:
match "object/:slug", :to => "my_objects#some_action"
答案 1 :(得分:1)
您可以使用Base64编码执行此操作(尽管如果您真的想保持内部ID秘密,有人可能会猜测您正在使用Base64编码并轻松确定ID。)
您的控制器需要看起来有点像这样
class ThingsController < ApplicationController
require 'base64'
def show
@thing = Thing.find Base64.urlsafe_decode64(params[:id])
end
def edit
@thing = Thing.find Base64.urlsafe_decode64(params[:id])
end
#These are just a couple of very simple example actions
end
现在实际编码你的网址会变得有点棘手 - 我会调查它,因为它似乎是一个有趣的问题(但我没有做出任何承诺)。
一些阅读揭示了ActionView使用url_for中的to_param方法来获取对象的id。我们可以在模型本身中覆盖它,以便像这样编码id
class Thing < ActiveRecord::Base
def to_param
Base64.urlsafe_encode64 self.id.to_s
end
end
我在这里写的所有东西都是猜测的。我之前没有这样做或测试过代码,所以我不能保证它是否会起作用或是否会引入无法预料的问题。我很想知道你怎么走。