1

我正在做一个让我难过的项目,希望有人能提供一些有趣的意见。我看到有几个可用于混淆 url 的 gem,但它们似乎停止在 slug 级别而不是控制器级别 - 即 www.foo.com/mycontroller/8sZ16lp。我正在寻找一种方法来产生类似于 www.foo.com/8asd31Ud 的内容,删除控制器名称。我检查了 obsufacate_id gem 的文档,但似乎并没有那么远。

提供更多背景信息 - 我真的希望有 www.foo.com/mycontroller/15/edit = www.foo.com/95Ali32

4

1 回答 1

0

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

于 2015-02-03T01:14:48.600 回答