【问题标题】:Simple Rails routing problem简单的 Rails 路由问题
【发布时间】:2011-05-23 02:50:30
【问题描述】:

我有另一个 ruby​​ nuby 时刻,似乎无法解决这个简单的问题。

我有这条路线:

resources :pages

我的页面控制器中有这个:

def testy

end

我在 app/views/pages/testy.html.erb 中有这个

<h1>Testy</h1>

我正在尝试像这样访问该页面:http://localhost:3000/pages/testy

我收到以下错误:

Couldn't find Page with ID=testy

这是日志:

Started GET "/pages/testy" for 127.0.0.1 at Thu Dec 09 14:24:51 -0600 2010
Processing by PagesController#show as HTML
Parameters: {"id"=>"testy"}
[1m[35mPage Load (0.3ms)[0m  SELECT "pages".* FROM "pages" WHERE ("pages"."id" = 0) LIMIT 1
Completed   in 12ms

ActiveRecord::RecordNotFound (Couldn't find Page with ID=testy):
app/controllers/pages_controller.rb:11:in `show'

从日志中可以明显看出它正在尝试访问#show,但为什么呢?我认为这是我的路线的问题。谁能给我一个快速的指针?

我一直在关注Rails Guides here,我认为这就是让我失望的原因“......规则是,如果您在控制器操作结束时没有明确呈现某些内容,rails 将查找 action_name。控制器视图路径中的 html.erb 模板,然后渲染它,..."

【问题讨论】:

标签: ruby-on-rails ruby routes


【解决方案1】:

当您设置像 resources :pages 这样的 RESTful 路由时,默认情况下,URL 中 pages/ 之后的任何内容都会作为 ID 放入 params 哈希中,因此 pages/1 会给您一个包含 {:id =&gt; '1'} 的 params 哈希(其中包括:controller、:action 等)。

pages/new 或 pages/edit 等某些操作存在例外情况。 Rails 足够聪明,知道“新”和“编辑”不是 ID。你只需要告诉 rails 'testy' 也不是一个 ID。

您可以在附加到resources 的块内使用member 或collection 定义自定义操作,如下所示:

resources :pages do
  collection do
    get :testy  # will match pages/testy
    get :foo
    post :bar
  end

  member do
    get :baz # will match pages/1/baz
  end
end

现在 rails 会知道 pages/testy 是一个自定义路由,并且不会将 'testy' 解释为一个 ID。确保您的路线名称永远不会与您的 ID 相同。换句话说,如果您有一个Page,由于某种原因,其 id 为testy,那么根据上述路线,您将永远无法到达它!

为了更深入的了解,我强烈推荐官方 rails guide on routes: http://guides.rubyonrails.org/routing.html

有点长,但绝对值得花时间阅读。

【讨论】:

  • @jyoseph 很高兴有帮助。我更新了答案以使用collection。
  • 我可以在其中嵌套多个集合,对吧?我做到了,而且似乎还可以。所以collection do get:testy end collection do get :cal end
  • 可以,但您无需重复collection。查看更新的答案。
【解决方案2】:

别忘了运行rake routes 或编写路由测试/规范

【讨论】:

    【解决方案3】:

    选项 1

      resources :pages do
        collection do
          get :testy
        end
      end
    

    结果:

    testy_pages GET /pages/testy(.:format) {:action=>"testy", :controller=>"pages"}
    

    选项 2

      resources :pages do
        member do
          get :testy
        end
      end
    

    结果:

    testy_page GET /pages/:id/testy(.:format) {:action=>"testy", :controller=>"pages"}
    

    选项 3

      resources :pages do
        get :testy
      end
    

    结果:

    page_testy GET /pages/:page_id/testy(.:format) {:action=>"testy", :controller=>"pages"}
    

    其中任何一个都可能有用,但我认为选项 1 是您所要求的。

    【讨论】:

      【解决方案4】:

      由于页面是资源,因此 URL 中的任何内容都将是带有股票期权的 id。

      如果您想定义一个以“testy”为名称的定义,您需要在您的routes.rb 中添加一个named routed,例如:

      map.test 'testy', :controller => "pages", :action => "test"
      

      然后要链接到此,您需要致电&lt;%= link_to "testy", testy_path %&gt;

      【讨论】:

        【解决方案5】:

        在您的路线文件中

        resources :pages do
          get 'test'
        end
        

        这将起作用。必要时替换为帖子

        【讨论】:

          猜你喜欢
          • 2011-08-29
          • 1970-01-01
          • 1970-01-01
          • 2011-01-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-01-05
          相关资源
          最近更新 更多