由于这不符合 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 支持)。