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

发布于 2024-07-23 14:51:23 字数 1236 浏览 5 评论 0原文

我希望我的 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

通过修改我的网站模型,我可以生成更好的 URL,如下所示:

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 不高兴。 我相信这是因为“.” 字符在 ActionController::Routing::SEPARATORS 中定义,它列出了用于分割 URL 的特殊字符。 这允许您执行 /websites/1.xml 之类的操作。

那么,有没有一种干净的方法来允许“.” RESTful URL 中的字符?

我尝试重新定义 ActionController::Routing::SEPARATORS 以不包含“.”,这是解决问题的完全糟糕的方法。 这会通过向生成的 URL 附加“.:format”来弄乱它们。

我也知道我可以添加:要求=> {:id => regexp } 到我的 config/routes.rb 以匹配包含“.”的域名 (如果没有这个,params[:id] 将设置为第一个“.”之前的域名部分),但这无助于以 REST 方式生成 URL/路径。

非常感谢 :) 缺口

I want my Rails 2.3.2 app to respond to and generate URLs like so:

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

In my config/routes.rb, I have:

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

I can then access resources such as:

/websites/1
/websites/1/dns_records

By modifying my Website model, I can generate better URLs like so:

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

However, for domain names that contain '.' characters, Rails gets unhappy. I believe this is because the '.' character is defined in ActionController::Routing::SEPARATORS, which lists special characters to split the URL on. This allows you to do stuff like /websites/1.xml.

SO, is there a clean way to allow '.' characters in RESTful URLs?

I've tried redefining ActionController::Routing::SEPARATORS to not include '.', which is a totally bad way to solve the problem. This messes up generated URLs by appending ".:format" to them.

I also know I can add :requirements => { :id => regexp } to my config/routes.rb to match a domain name that includes '.' (without this, params[:id] is set to the part of the domain name before the first '.'), but this doesn't help in generating URLs/paths RESTfully.

Many thanks :)
Nick

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

空城缀染半城烟沙 2024-07-30 14:51:23

解决了问题,非常感谢 http://poocs .net/2007/11/14/special-characters-and-nested-routes(并参见 http://dev.rubyonrails.org/ticket/6426 以获得更多参考)

我需要添加 :requirements => { :website_id =>; 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 保持一致,这样就不必为网站的所有嵌套路由指定 :requirements 。 所以我也可以有

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

Solved the problem, with a big thanks to http://poocs.net/2007/11/14/special-characters-and-nested-routes (and see http://dev.rubyonrails.org/ticket/6426 for additional reference)

I needed to add :requirements => { :website_id => regexp } for each nested route that was also going to include a domain name with periods in it.

Here's my working route:

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

The call to

websites.with_options

is simply in keeping with DRY so that :requirements don't have to be specified for all nested routes for websites. So I could also have

websites_requirements.resources :accounts
websites_requirements.resources :monthly_bandwidth_records
etc.
有深☉意 2024-07-30 14:51:23

这是一个有趣的问题。 我认为如果您执行基本的map.resources,您就无法摆脱附加到末尾的错误'.:format'。 如果您希望名称中包含句点,则说明您不符合通常的 Rails 样式,并且我认为如果您绝对需要“。”,则自定义路线可能是合适的。 在网址中。

但是,也许您应该考虑更改 to_param 的定义。 如果使用以下内容,您会想到什么?

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

我认为,如果您使用它来管理客户网站,这是一种相当优雅的方式来生成漂亮的(并且 SEO 友好的)URL,例如

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

This is an interesting issue. I don't think you can get rid of the bad '.:format' appended to the end if you do a basic map.resources. If you want periods in the names, you are not in accordance with the usual rails styles, and I think a custom route might be in order if you absolutely NEED the '.' in the URL.

However, maybe you should consider changing your definition of to_param. What would you think about using the following?

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

I think, if you're using this to manage customer websites, it's a fairly elegant way to generate nice (and SEO friendly) URLs like

/websites/asd_dot_com/dns_records/new
/websites/asd_dot_com/
囚我心虐我身 2024-07-30 14:51:23

我前段时间遇到了类似的问题并得出了类似的解决方案。 使用 /.+/ 作为相关参数的要求对我来说效果很好。

http://zargony.com/2009/05/05/带点的路由参数

I had a similar issue some time ago and came to a similar solution. Using /.+/ as the requirement for the param in question worked fine for me.

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文