I have a rule in my routes.rb:
constraints AssetRestrictor do
match '*seopath' => SeoDispatcher
end
Then in lib/seo_dispatcher.rb, I have this:
class SeoDispatcher
AD_KEY = "action_dispatch.request.path_parameters"
def self.call(env)
seopath = env[AD_KEY][:seopath]
if seopath
params = seopath.split('/') # get array of path components
env[AD_KEY][:id] = params.last # the real page name is the last element
env[AD_KEY][:category] = params.first if params.length > 1
end
Rails.logger.debug "routing to show #{env[AD_KEY]}"
PagesController.action(:show).call(env)
# TODO error handling for invalid paths
end
end
class AssetRestrictor
EXCEPTION_FILES = ['javascripts', 'stylesheets', 'autodiscover']
def self.matches?(request)
return false if request.method == 'POST' # no post requests are SEO-ed
EXCEPTION_FILES.each do |ex|
return false if request.url.include?(ex)
end
true
end
end
And basically, the whole thing works. The idea is to peel off the last path component and match it to the slug for a page. SEO people tell me this is the cool way to trick search engines into ranking you higher.
My snarky comments aside, I'm having trouble writing a test in rSpec that exercises this code. My first shot at it was:
describe SeoDispatcher do
it "routes /insurance/charters-and-guides/how-to-buy-charter-boat-insurance to pages#show :id => how-to-buy-charter-boat-insurance" do
{ :get => "/insurance/charters-and-guides/how-to-buy-charter-boat-insurance"}.should route_to(
:controller => 'pages',
:action => 'show',
:id => 'how-to-buy-charter-boat-insurance'
)
end
end
But this simply doesn't exercise the Rack dispatch code. Does anyone know how one would (than cuking it) exercise the code? I really want to bring the parameters in from Rack instead of just doing SeoDispatcher.call({"action_dispatch.request.path_parameters" => {:seopath => "/foo/bar"}})
.
Thanks!
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…