将动作添加到现有控制器(Ruby on Rails)
我是Ruby on Rails的新手,我已经完成了博客教程 。
我现在试图添加一个额外的动作到控制器,称为“开始”。
def start end
我添加了一个视图页面“app / views / posts / start.html.erb”,只包含简单的html。
当我去/ posts / start我得到以下错误。
ActiveRecord::RecordNotFound in PostsController#show Couldn't find Post with ID=start
我明白错误,显示操作正在执行,并且启动不是有效的ID。 为什么启动操作不能执行,是否有一部分MVC架构或configuration丢失?
以下是我的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。
您的路由没有设置为允许该路由。 假设你使用了默认的脚手架,把这行放在config / routes.rb中的map.resources :posts
行之前:
map.connect "posts/:action", :controller => 'posts', :action => /[az]+/i
正则expression式:action
将其限制为只有az(以避免捕获/ posts / 1之类的东西)。 如果您在新操作中需要下划线或数字,则可以进行改进。
你所犯的错误实际上是一个很常见的错误。
基本上,Rails会自动映射脚手架的URL。 所以当你创buildPosts脚手架时,Rails会为它的URL路由映射。 一个这样的路线是查看单个post的URL:/ posts /(post_id)
所以,当你inputURL / posts / start时,Rails认为你的意思是“嘿,给我一个ID = start的post,所以Rails抱怨show方法找不到这个ID的post。
解决这个问题的一个快速方法是确保你的config / routes.rb脚本path之前有启动动作的路由:
# Route for start action map.connect '/posts/start', :controller => 'posts', :action => 'start' # Default mapping of routes for the scaffold map.resources :posts
无论如何,希望有所帮助。
在Rails 4.x上使用:
get '/posts/start', :controller => 'posts', :action => 'start'
在Rails 3.x上使用:
match '/posts/start', :controller => 'posts', :action => 'start'
代替
map.connect '/posts/start', :controller => 'posts', :action => 'start'
它解决了我的问题。
如果你使用rails 3.0.3,试试这个
在你的route.rb
resource :posts do collection do get 'start' end end
这可能有帮助
我想说的是,即使在开发环境中,有时Rails也会对路由caching产生粘性。
这可能有助于重新启动您的Rails服务器 。 这在接收到这个错误的时候比我能算的更多。
这工作:
map.resource :post, :collection => { :my_action => :get}
我find了解决我的问题,在routes.rb文件中
map.resource :post
我添加了收集参数,所以它保持这种方式:
map.resource :post, :collection => { :my_action => :get}