简单的Rails路由问题

时间:2010-12-09 20:36:33

标签: ruby-on-rails ruby routes

我有另一个红宝石的时刻,似乎无法绕过这个简单的问题。

我将此作为一条路线:

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模板,然后渲染,...“

5 个答案:

答案 0 :(得分:5)

当您设置像resources :pages这样的RESTful路由时,默认情况下,URL中的pages/之后的所有内容都会作为ID放入params哈希,因此pages/1会为您提供一个参数哈希其中包括{:id => '1'}(以及:controller:action等内容)。

pages/newpages/edit等特定操作有例外。 Rails足够聪明,知道“新”和“编辑”不是ID。你只需告诉rails,'testy'也不是一个ID。

您可以使用membercollection内的resources定义自定义操作,如下所示:

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,那么鉴于上述路线,你永远无法达到它!

为了更深入的了解,我强烈推荐路线上的官方铁路指南: http://guides.rubyonrails.org/routing.html

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

答案 1 :(得分:2)

选项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是你要求的。

答案 2 :(得分:1)

路线文件中的

resources :pages do
  get 'test'
end

这将有效。如有必要,请更换帖子

答案 3 :(得分:1)

不要忘记运行rake routes或编写路由测试/规范

答案 4 :(得分:0)

由于网页是资源,因此网址中的任何内容都是带有股票期权的id

如果您希望定义“testy”作为名称,则需要向named routed添加routes.rb,例如:

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

然后要链接到此,您需要致电<%= link_to "testy", testy_path %>