【发布时间】:2011-08-04 05:58:36
【问题描述】:
我的 routes.rb 中有一条规则:
constraints AssetRestrictor do
match '*seopath' => SeoDispatcher
end
然后在 lib/seo_dispatcher.rb 中,我有这个:
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
基本上,整个事情都有效。这个想法是剥离最后一个路径组件并将其与页面的 slug 匹配。搜索引擎优化的人告诉我,这是欺骗搜索引擎让你排名更高的好方法。
撇开我那刻薄的 cmets 不谈,我在 rSpec 中编写一个运行此代码的测试时遇到了麻烦。我的第一枪是:
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
但这根本不执行机架调度代码。有谁知道一个人将如何(而不是 cuking)行使代码?我真的很想从 Rack 中引入参数,而不仅仅是 SeoDispatcher.call({"action_dispatch.request.path_parameters" => {:seopath => "/foo/bar"}})。
谢谢!
【问题讨论】:
标签: ruby-on-rails rack