【问题标题】:Adding an action to an existing controller (Ruby on Rails)向现有控制器添加操作(Ruby on Rails)
【发布时间】:2008-12-30 19:37:02
【问题描述】:

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

我现在正在尝试向控制器添加一个额外的操作,称为“开始”。

def start
end

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

当我转到 /posts/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 进行了尝试。

【问题讨论】:

  • 请重新标记...“on”不应该是标记

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


【解决方案1】:

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

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

所以,当您输入 URL /posts/start 时,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

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

【讨论】:

  • 感谢您的解释,我将不得不阅读更多关于路线的信息。
  • 我认为在尝试理解 RoR 中的路由如何工作时,最有帮助的一件事是记住它们是从上到下进行评估的。因此,通常最好的做法是在一般(包罗万象)路线之前拥有更具体的路线。
  • 我使用了 match '/pages/action', :controller => 'pages', :action => 'action' 并且成功了。
【解决方案2】:

在 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'

它解决了我的问题。

【讨论】:

    【解决方案3】:

    您的路由未设置为允许该路由。假设您使用的是默认脚手架,请将这一行放在 config/routes.rb 中的map.resources :posts 行之前

    map.connect "posts/:action", :controller => 'posts', :action => /[a-z]+/i
    

    :action 的正则表达式将其限制为 a-z(以避免捕获 /posts/1 之类的内容)。如果您在新操作中需要下划线或数字,则可以改进它。

    【讨论】:

      【解决方案4】:

      如果您使用的是 rails 3.0.3,请尝试此操作

      在你的 route.rb 中

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

      这可能会有所帮助

      【讨论】:

        【解决方案5】:

        我想说,有时 Rails 对路由缓存很敏感,即使在 开发 环境中也是如此。

        重新启动 Rails 服务器可能会有所帮助。这对我有用的次数比我收到此错误时的次数还要多。

        【讨论】:

          【解决方案6】:

          这行得通:

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

          【讨论】:

          • 在 Rails 3 中,收集选项将 "collection"=&gt;{"my_action"=&gt;:get} 添加到 GET 参数中。
          【解决方案7】:

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

          map.resource :post
          

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

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

          【讨论】:

          • 在 Rails 3 中,这会将 "collection"=&gt;{"my_action"=&gt;:get} 添加到 GET 参数中。
          猜你喜欢
          • 1970-01-01
          • 2011-12-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-12-28
          • 2013-04-22
          • 1970-01-01
          • 2012-04-02
          相关资源
          最近更新 更多