我正在做一个让我难倒的项目,希望有人能有一些有趣的意见。 我看到有几个 gem 可用于混淆 url,但它们似乎停止在 slug 级别而不是控制器级别 - 即 www.foo.com/mycontroller/8sZ16lp。我正在寻找一种方法来生成类似 www.foo.com/8asd31Ud 的东西,删除控制器名称。 我检查了obsufacate_id宝石的文档,但它似乎并没有走那么远。
提供更多背景 - 我真的希望有 www.foo.com/mycontroller/15/edit = www.foo.com/95Ali32
由于这与 rails RESTful URL 的约定不符,我的猜测是您可能只需要编写自己的路由,甚至更多。出于好奇,您如何设想系统知道使用"95Ali32"加载什么类型的对象?这可能最好使用 Sinatra 构建,或者可以让您更好地控制路由和减少约定的东西。
下面是一种可能的方法,该方法使用映射到类型和对象 ID 的 slug 表:
# migration
create_table :slugs do |t|
t.string :object_type, :null => false
t.string :object_id, :null => false
t.string :slug
t.timestamps
end
# models
class Slugs < ActiveRecord::Base
belongs_to :object, :polymorhic => true
end
class AModel < ActiveRecord::Base
has_one :slug, :as => :owner
end
# routes.rb
# note that anything else should go above this because this will catch all other URL's
get '*slug', to: 'slugs#show'
# controller
class SlugsController < ApplicationController
def show
@object = Slug.where(slug: params[:slug])
raise ActiveRecord::NotFound.new unless @object
render @object.kind
end
end
然后,您需要为每种类型的对象构建视图。查看此相关问题
更新
这是另一个想法。你需要蛞蝓有多晦涩?如果每个模型都有一个已知代码,然后以某种方式对 ID 进行编码并附加到模型代码中,该怎么办?然后,您可以使用预配置的路由在代码中执行更简单的操作:
# You could generate this too, or just hard-code them
prefixes = ['8sZ', '95Ali']
[:a_model, :another_model].each do |model|
match "#{prefixes.pop}:id", :controller => model.to_s.underscore.pluralize, :action => :show, :as => model
end
这将为您提供这样的路线
/8sZ1 #=> AModelsController#show(:id => 1)
/95Ali341 #=> AModelsController#show(:id => 341)
你可以再提升一个级别,并使用friendly_id为模型 ID 生成 slug。或者使用UUID而不是整数ID(PostgreSQL支持)。