问题
I'm working on a project that's left me stumped, hoping someone out there might have some interesting input. I see there are several gems available for obfuscation of urls, but they seem to stop at the slug level instead of the controller level - i.e. www.foo.com/mycontroller/8sZ16lp. I'm looking for a method to produce something along the lines of www.foo.com/8asd31Ud, dropping the controller name. I checked the docs of the obsufacate_id gem, but it doesn't appear to go that far.
To give more background - I'm really hoping to have www.foo.com/mycontroller/15/edit = www.foo.com/95Ali32
回答1:
As this doesn't match the convention of rails RESTful URL's my guess is you'll likely just need to write your own routes and maybe more. Out of curiosity, how would you envision that the system knows what type of object to load with "95Ali32"? This might be better to build with Sinatra or something that gives you more control over the routing and less convention.
Here's one possible approach that uses a table with your slugs that maps to type and object id:
# 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
You would then need to build views for each type of object. See this related question
Update
Here's another idea. How obscure do you need the slug? What if each model has a known code and then the ID is encoded some way and appended to the model code? Then you could do something much simpler in the code using routes that are preconfigured:
# 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
This would give you routes like these
/8sZ1 #=> AModelsController#show(:id => 1)
/95Ali341 #=> AModelsController#show(:id => 341)
You could take this another level and use friendly_id to generate slugs for the model ID's. Or use UUID's instead of integer ID's (supported by PostgreSQL).
来源:https://stackoverflow.com/questions/28289515/obfuscation-of-urls-rails