向现有控制器添加操作(Ruby on Rails)

时间:2008-12-30 19:37:02

标签: ruby-on-rails ruby rails-routing

我是Ruby on Rails的新手,我已经完成了Blog Tutorial

我现在正在尝试向控制器添加一个名为“start”的附加操作。

def start
end

我添加了一个视图页面“app / views / posts / start.html.erb”,只包含简单的html。

当我去/ post / start时,我收到以下错误。

ActiveRecord::RecordNotFound in PostsController#show 
Couldn't find Post with ID=start

我理解错误,正在执行show动作并且start不是有效的ID。为什么启动操作没有执行,是否存在我缺少的MVC架构或配置的某些部分?

以下是我的posts_controller.rb

class PostsController < ApplicationController

  # GET /posts/start
  def start
  end

  # GET /posts
  # GET /posts.xml
  def index
    @posts = Post.find(:all)
    respond_to do |format|
      format.html # index.html.erb
      format.xml  { render :xml => @posts }
    end
  end

  # GET /posts/1
  # GET /posts/1.xml
  def show
    @post = Post.find(params[:id])
    respond_to do |format|
      format.html # show.html.erb
      format.xml  { render :xml => @post }
    end
  end

end

是的,我已经重新启动了服务器并尝试使用Mongrel和webrick。

7 个答案:

答案 0 :(得分:45)

您所犯的错误实际上是非常常见的。

基本上,Rails会自动为您的脚手架映射网址。因此,当您创建Posts脚手架时,Rails会为其绘制URL路由。一个这样的路线是用于查看单个帖子的URL:/ posts /(post_id)

所以,当你输入网址/帖子/开始时,Rails认为你在说“嘿,给我一个ID = start的帖子。所以Rails抱怨show方法无法找到带有这样ID的帖子

解决此问题的一种快速方法是确保您的config / routes.rb在脚手架路由之前具有启动操作的路由:

# Route for start action
map.connect '/posts/start', :controller => 'posts', :action => 'start'
# Default mapping of routes for the scaffold
map.resources :posts

无论如何,希望有所帮助。

答案 1 :(得分:33)

On Rails 4.x使用:

get '/posts/start', :controller => 'posts', :action => 'start'

On Rails 3.x使用:

match '/posts/start', :controller => 'posts', :action => 'start'

而不是

map.connect '/posts/start', :controller => 'posts', :action => 'start'

它解决了我的问题。

答案 2 :(得分:26)

您的路由未设置为允许该路由。假设您正在使用默认的脚手架,请将此行放在 {/ 1}}行中的config / routes.rb中:

map.resources :posts

map.connect "posts/:action", :controller => 'posts', :action => /[a-z]+/i 的正则表达式将其限制为a-z(以避免捕获/ posts / 1之类的内容)。如果您在新操作中需要下划线或数字,则可以进行改进。

答案 3 :(得分:8)

如果您使用的是rails 3.0.3

,请尝试此操作 你的route.rb

中的

 resource :posts do
   collection do
     get 'start'
   end
 end

这可能会有所帮助

答案 4 :(得分:2)

我想说,即使在开发环境中,Rails也会因路由缓存而变得棘手。

重新启动Rails服务器可能有所帮助。这对我来说比我收到这个错误时可以计算的次数多。

答案 5 :(得分:1)

这有效:

map.resource :post, :collection => { :my_action => :get}

答案 6 :(得分:0)

我在routes.rb文件中找到了我的问题的解决方案

map.resource :post

我添加了collection参数,所以它保持这种方式:

map.resource :post, :collection => { :my_action => :get}