使用to_param为包含分隔符的字段使用Rails RESTful资源

时间:2009-06-04 06:31:26

标签: ruby-on-rails rest separator

我希望我的Rails 2.3.2应用响应并生成如下所示的URL:

/websites/asd.com
/websites/asd.com/dns_records/new

在我的config / routes.rb中,我有:

map.resources :websites, :has_many => :dns_records
map.resources :dns_records, :belongs_to => :website

然后我可以访问资源,例如:

/websites/1
/websites/1/dns_records

通过修改我的网站模型,我可以生成更好的网址:

class Website < ActiveRecord::Base
    def to_param
        domain_name
    end
    ...
end

# app/views/websites/index.erb
<% @websites.each do |w| %>
<%= link_to "Show #{w}", website_path(w) %>
<% end %>

# Produces a link to:
/websites/example_without_periods_in_name

但是,对于包含“。”的域名。人物,Rails变得不快乐。我相信这是因为'。' character在ActionController :: Routing :: SEPARATORS中定义,它列出了用于拆分URL的特殊字符。这允许你做像/websites/1.xml这样的东西。

那么,是否有一种干净的方式允许'。' RESTful URL中的字符?

我尝试重新定义ActionController :: Routing :: SEPARATORS以不包含'。',这是解决问题的一种非常糟糕的方法。这会通过在其中附加“。:format”来混淆生成的URL。

我也知道我可以添加:requirements =&gt; {:id =&gt; regexp}到我的config / routes.rb以匹配包含'。'的域名。 (没有这个,params [:id]被设置为第一个'。'之前的域名部分),但这无助于RESTful地生成URL /路径。

非常感谢:) 尼克

3 个答案:

答案 0 :(得分:4)

解决了这个问题,非常感谢http://poocs.net/2007/11/14/special-characters-and-nested-routes(另请参阅http://dev.rubyonrails.org/ticket/6426

我需要添加:requirements =&gt; {:website_id =&gt;对于每个嵌套路由,regexp}也包含一个包含句点的域名。

这是我的工作路线:

map.resources :websites, :requirements => { :id => /[a-zA-Z0-9\-\.]+/ } do |websites|
    websites.with_options :requirements => { :website_id => /[a-zA-Z0-9\-\.]+/ }  do |websites_requirements|
        websites_requirements.resources :dns_records
    end
end

<%= link_to 'New DNS Record', new_website_dns_record_path(@website) %>

# Produces the URL
/websites/asd.com/dns_records/new

致电

websites.with_options

与DRY保持一致,因此:不必为网站的所有嵌套路由指定要求。所以我也可以

websites_requirements.resources :accounts
websites_requirements.resources :monthly_bandwidth_records
etc.

答案 1 :(得分:1)

这是一个有趣的问题。如果你做一个基本的'.:format',我认为你不能摆脱附加到最后的坏map.resources。如果你想要名字中的句点,你就不符合通常的栏目风格,而且如果你绝对需要'',我认为自定义路线可能是有序的。在网址中。

但是,您可以考虑更改to_param的定义。您对使用以下内容有何看法?

def to_param
   domain_name.sub('.','_dot_')
end

我认为,如果您使用它来管理客户网站,那么生成好的(和SEO友好的)网址是一种相当优雅的方式,例如

/websites/asd_dot_com/dns_records/new
/websites/asd_dot_com/

答案 2 :(得分:0)

前段时间我遇到过类似的问题,并找到了类似的解决方案。使用/.+/作为有问题的参数的要求对我来说很好。

http://zargony.com/2009/05/05/routing-parameters-with-a-dot