【问题标题】:How to generate links with RESTful routes on Rails?如何在 Rails 上生成带有 RESTful 路由的链接?
【发布时间】:2016-09-23 12:44:18
【问题描述】:

我在使用链接到当前控制器上名为“Clients”的“New”操作的按钮时遇到问题。

点击后会显示 Rails 路由错误:

没有路由匹配 [POST] "clients/new"

这是我正在使用的产生错误的代码:

<%= button_to("New Client", new_client_path, :class => "btn btn-lg btn-primary pull-right add-button" ) %>

如果我将路径更改为clients_path,如下所示:

<%= button_to("New Client", clients_path, :class => "btn btn-lg btn-primary pull-right add-button" ) %>

然后我得到以下错误:

未知操作。找不到 ClientsController 的“创建”操作

控制器操作新建和创建:

def new
  @client = Client.new
end

def create
  @client = Client.new(client_params)

  if @client.save
    flash[:notice] = "Client added succesfully."
    redirect_to client_path(@client)
  else
    render 'new'
  end
end

routes.rb 文件包含以下内容:

Rails.application.routes.draw do

  get 'clients/index'

  get 'clients/show'

  get 'clients/new'

  get 'clients/edit'

  get 'clients/delete'

  resources :clients

end

现在clients 是我创建的唯一资源。使用 RESTful 路由轻松创建链接我缺少什么?

【问题讨论】:

    标签: ruby-on-rails rest routing


    【解决方案1】:

    需要进行一些更改才能使其适合您。首先,您的路线是多余的并且与 Rails 约定冲突。您应该删除所有 get 路由并只使用 resources 路由。这就是您的客户路线所需的全部内容:

    Rails.application.routes.draw do
    
        # notice, no "get" routes
    
        resources :clients
    end
    

    接下来,button_to 默认为POST 方法,因此在使用GET 路由时必须覆盖它的方法。请参阅button_to API documentation 了解更多信息。

    试试这个吧:

    <%= button_to("New Client", new_client_path, { method: :get, :class => "btn btn-lg btn-primary pull-right add-button" } ) %>
    

    请注意,button_to 与许多 ActionView 表单助手一样,接受 2 个单独的哈希值,第一个是 options,第二个是 html_options。分离散列值很重要,否则您将无法获得所需的行为。 method 和 class 选项进入 html_options。如果您的调用中只有一个选项哈希(大括号是可选的),Ruby 会将它们分配给 最后一个哈希参数;您可以显式提供所有哈希值,以使代码的读者清楚您的意图,如下所示:

    <%= button_to("New Client", new_client_path, {}, { method: :get, :class => "btn btn-lg btn-primary pull-right add-button" } ) %>
    

    最后,尝试使用clients_path 路由助手导致ClientController#index 方法的路径(例如/clients),伴随着看似无关的create 方法错误。 create 操作是 POST 路由,其 URL 路径与 index 操作相同。如果您查看此资源的 rake routes 的输出,您将看到以下内容:

          Prefix Verb   URI Pattern                 Controller#Action
         clients GET    /clients(.:format)          clients#index
                 POST   /clients(.:format)          clients#create
      new_client GET    /clients/new(.:format)      clients#new
     edit_client GET    /clients/:id/edit(.:format) clients#edit
          client GET    /clients/:id(.:format)      clients#show
                 PATCH  /clients/:id(.:format)      clients#update
                 PUT    /clients/:id(.:format)      clients#update
                 DELETE /clients/:id(.:format)      clients#destroy
    

    查看clients(在“前缀”下)如何匹配路径/clients 的GET,在其正下方,有一个未命名的POST 条目指向相同的/clients 路径。在最右侧,您可以看到GET 方法路由到clients#index 操作,而POST 方法路由到clients#create 操作。

    在这种情况下,button_to 的默认方法是 POST,它试图路由到 clients#create 操作,这不是您想要做的。您几乎不应该直接向create、update 或destroy 方法发送任何内容,并且在您这样做的少数情况下,您会非常故意地这样做,并且很清楚这是不正常的(不是不正确,只是异常)Rails 使用。

    【讨论】:

    • 这解决了我的问题,但不得不做出一些改变,而不是 &lt;%= button_to("New Client", clients_path, { method: :get }, { :class =&gt; "btn btn-lg btn-primary pull-right add-button" } ) %&gt;,我不得不修改从 clients_path 到 new_client_path 的路由,并且因为一个大括号内的方法和类参数数量无效错误。它最终像这样工作:&lt;%= button_to("New Client", new_client_path,{ method: :get, class: 'btn btn-lg btn-primary pull-right add-button' } ) %&gt;。请编辑答案以标记为已回答。
    • @JorgeCuevas 很好的反馈,感谢您告诉我!我已经更新了答案,并添加了关于button_to 的两个哈希的更多解释。 new_client_path 问题是复制/粘贴错误,哈希选项问题是对文档的误读。现在这些都整理好了,准备好让你确认。谢谢!
    • 一切似乎都很好,希望这能帮助其他人在未来遇到类似问题。感谢您的帮助 Michael,标记为已回答。
    【解决方案2】:

    请检查您的routes.rb,并确保您已添加resources :clients。

    您还应该查看documentation,看看您是否错误地调用了您的路线。

    例如。 clients_new_path 应该是 new_client_path

    如果您进行了这两项更改,但仍有问题。看起来错误将出现在您的 ClientsController 中。

    确保您已添加 create 操作。

    def create
    @client = Client.new(client_params)
    
    if @client.save
      flash[:notice] = 'App successfully created!'
      redirect_to client_path(@client)
    else
      flash[:error] = @app.errors.full_messages.join(', ')
      render 'new'
    end
    

    结束

    【讨论】:

    • routes.rb 文件包括资源 :clients,以及为每个视图自动生成的 get 路由。我尝试更改为 new_client_path 但它显示完全相同的路由错误消息。
    • 我有它但是是空的。填充它但显示相同的错误。我在路线文件上遗漏了什么吗?
    • 在原帖中添加了Controller和routes.rb文件。
    【解决方案3】:

    这样试试:

    <%= button_to("New Client", new_client_path, :class => "btn btn-lg btn-primary pull-right add-button" ) %>
    

    您必须使用“客户端”,而不是“客户端”来创建单个客户端

    【讨论】:

    • 已经按照前一个问题的建议尝试过,点击时仍然显示相同的错误。编辑了帖子以显示问题的当前状态。
    • 你能发布你的client_conroller.rb吗?
    • 添加到原帖中。
    猜你喜欢
    • 2012-09-26
    • 2013-06-04
    • 1970-01-01
    • 2011-09-22
    • 2019-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多