【问题标题】:How can I change the default parameter names in Rails 3 routing?如何更改 Rails 3 路由中的默认参数名称?
【发布时间】:2011-03-22 14:12:21
【问题描述】:

在我的 Rails 3 项目中,我有一个这样的路线列表:

resources :projects do
    resources :studies
end

resources :sticky_notes
resources :study_templates

...

目前默认情况下,可以使用 params[:id] 调用这些路由中的 URL 中的 id,但我希望能够使用 params[:sticky_note_id]、params[:study_template_id]、params[:study_id] 调用它们]等。有没有办法可以为这些项目的ID指定参数名称?我是否必须在没有“资源”的情况下手动写出每条路线?

谢谢!

编辑:这是我正在尝试做的一个例子: 这就是当路由如上所写时会发生的情况:

resources :projects do
    resources :studies
end
# results in /projects/:project_id/studies/:id
# /projects/:project_id/studies/:id/edit
# /projects/:project_id/studies/:id/new
# etc.

resources :sticky_notes
# results in /sticky_notes/:id
# /sticky_notes/:id/edit
# /sticky_notes/:id/new
# etc.

这就是我想要的:

match '/projects/:project_id/studies/:study_id' => 'studies#show'
match '/projects/:project_id/studies/:study_id/edit' => 'studies#edit'
match '/projects/:project_id/studies/:study_id/new' => 'studies#new'
...

# results in /projects/:project_id/studies/:study_id
# /projects/:project_id/studies/:study_id/edit
# etc

match '/sticky_notes/:sticky_note_id' => 'sticky_notes#show'
match '/sticky_notes/:sticky_note_id/edit' => 'sticky_notes#edit'
match '/sticky_notes/:sticky_note_id/new' => 'sticky_notes#new'
...

# results in /sticky_notes/:sticky_note_id
# /sticky_notes/:sticky_note_id/edit
# etc

我想要第二部分,但在我已经很大的路线文件上没有所有这些工作。 :) 有可能吗?

【问题讨论】:

  • 只是出于好奇:你为什么要这样做?有什么好处?
  • 我有很多嵌套路由,以及没有嵌套路由也可以访问的页面(即有项目/X/studies/Y 和研究/Y)。其中一个问题是我正在尝试创建一个通用的“笔记”系统,该系统根据 URL 中的参数(study_id、project_id 等)存储笔记。如果我可以通用地指定 id 名称而不是总是测试 params[:study_id].nil?,如果是,则使用 params[:id],如果不使用 [:study_id] 等等,这将更容易做到。
  • 如果为 projects/:project_id/studies/:id 和 projects/:project_id/studies/:study_id 设置路线有意义的话,我会两者都做,我只是不知道是否有除了写出所有路线之外的一种简单方法(呃)
  • 我明白了!这样一来,控制器可能会变得非常拥挤。我在某些项目上遇到了同样的问题。让我们希望有一个好的答案:)
  • If it would make sense to have routes for both projects/:project_id/studies/:id and projects/:project_id/studies/:study_id I would do both. Route projects/:project_id/studies/:id 只是一个匹配器,params[:id]params[:study_id] 都会匹配。因此,如果您将两者都写,那么只有最上面的那个才有效。这不是路线问题,而是控制器。您应该提供:id,例如:type.

标签: ruby-on-rails ruby ruby-on-rails-3


【解决方案1】:

毕竟 'routes.rb' 只是一个简单的 ruby​​ 文件,所以为什么不使用 ruby​​ 代码,甚至可以创建一个方法来生成必要的路由.. 让我们看一个使用资源数组的简单示例,如果您想使用嵌套资源,您可能需要修改方法以使用哈希链以传递您要添加成员的资源:

def add_nested_resource(toadd=nil, controller=nil, resources=[])
  return if toadd.nil? || controller.nil? || ressources.empty?
  resources.each { |x|
    resources x do
      resources toadd, :controller => controller
    end
  }
end

add_nested_resource(:notes, "notes", [:resource1, :resource2, ..., :resourceX]

相当于

resources :resource1 do
  resources :notes, :controller => "notes"
end
resources :resource2 do
  resources :notes, :controller => "notes"
end
.
.
.
resources :resourceX do
  resources :notes, :controller => "notes"
end

这样您就可以轻松编写大量路线。 当然,在 notes_controller 中,您可能必须区分哪个资源调用了它,我通常在相应的表单中添加一个隐藏字段,在其中我留下嵌套嵌套对象的对象的“分类”名称......就像

<%= form_for ... someform for resource1... do |f| %> 
 ...
 <%= hidden_field_tag :nesting_object, "Resource1" %>
 ...
<% end %>

希望这可以帮助您度过难关...

【讨论】:

  • 你当然可以编写一个方法来生成路由。这自然意味着您必须设置一个散列/数组类型的容器来定义您想要生成的内容......这又可能是很多工作。除此之外,只想到元编程。我的意思是在 ruby​​ 中,你总是可以重新打开一个类并覆盖一个方法。因此,完成此操作的最佳方法可能是重新打开负责设置路由的类并覆盖使用 ":#{object.singularize}_id" 进行路由生成的方法,无论它默认使用 ":id" 耸耸肩不知道那在哪里......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-03-22
  • 1970-01-01
  • 2020-04-26
  • 2011-09-29
  • 1970-01-01
  • 2015-12-20
  • 1970-01-01
相关资源
最近更新 更多