2

在编辑时添加,2013-02-11:

我应该更清楚地说明我遇到的问题不是我无法获得我编写的 ERB 代码来生成正确的 HTML 代码。相反,我的 Rails 安装有时会正确解释 HTML 代码,因此单击链接会产生正确的效果,有时会不正确,产生“无路由”错误。我在下面的答案中提供了更多详细信息。

原始问题,2013-02-08:

我正在使用 Rails 3.2.11 制作一个简单的登录表单。我尝试了几种对表单的提交按钮进行编码的方法,但由于缺少路由错误,每种方法都失败了。我有一种方法可以工作,并检查了我的代码。然而,现在同样的代码失败了。

这是app/views/session/new.html.erb(我正在使用simple_form,但不是它的按钮包装器)的代码:

<h2>Log in</h2>
<%= simple_form_for :session do |f| %>
  <%= f.input :username %>
  <%= f.input :password %>
  <%= button_to "Submit", session_index_path %>
<% end %>

这产生的 HTML 代码的相关部分是:

<h2>Log in</h2>
<form accept-charset="UTF-8" action="/session/new" class="simple_form session" method="post" novalidate="novalidate">
  <div style="margin:0;padding:0;display:inline">...</div>
  ...the input fields...
  <form action="/session" class="button_to" method="post">
    <div>
      <input type="submit" value="Submit" />
      <input name="authenticity_token" type="hidden" value="...token value here..." />
    </div>
  </form>
</form>

这是我的config/routes.rb

MyApp::Application.routes.draw do
  resources :at_user
  resources :session, :only => [:new, :create, :destroy]
  match 'login'  => 'session#new',     as: :login
  match 'logout' => 'session#destroy', as: :logout
  root to: 'main#index'
end

这是命令rake routes输出的内容:

at_user_index GET    /at_user(.:format)          at_user#index
              POST   /at_user(.:format)          at_user#create
  new_at_user GET    /at_user/new(.:format)      at_user#new
 edit_at_user GET    /at_user/:id/edit(.:format) at_user#edit
      at_user GET    /at_user/:id(.:format)      at_user#show
              PUT    /at_user/:id(.:format)      at_user#update
              DELETE /at_user/:id(.:format)      at_user#destroy
session_index POST   /session(.:format)          session#create
  new_session GET    /session/new(.:format)      session#new
      session DELETE /session/:id(.:format)      session#destroy
        login        /login(.:format)            session#new
       logout        /logout(.:format)           session#destroy
         root        /                           main#index

的目标路径button_tosession_index_path,这应该会导致create方法SessionController被调用——有一段时间,它确实如此。现在,在我重新启动 Rails 后,按下按钮会产生一个错误页面,其中包含文本

No route matches [POST] "/session/new"

出于某种原因,Rails 开始认为 的目标button_tosession#new而不是session#create. 就好像它认为它应该调用的 HTTP 方法是 GET 而不是 POST——但是,HTML 代码显示该方法是 post。

顺便说一句,我之前尝试过的另一件事是提供button_to动作和方法参数,如此所述:

<%= button_to "Submit", options: {action: 'create', method: :post} %>

那么这就是生成的:

<form action="/session/new?options%5Baction%5D=create&amp;options%5Bmethod%5D=post" class="button_to" method="post">

这看起来也不是我想要的。 button_to的默认 HTTP 方法是 POST,它出现在结果中,但:options散列只是添加到 URL 的末尾,并且该词create没有出现在其他任何地方。

这个问题的第一个答案说,与文档所说的不同,不应将参数button_to放在散列中,而应直接提供。所以,我尝试了这个:

<%= button_to "Submit", action: 'create' %>

但是,该操作create仍然没有显示在生成的 HTML 中:

<form action="/session" class="button_to" method="post">

所以,这些是我在尝试使用命名路径方法之前尝试过的事情,它工作了一分钟,但由于某种神秘的原因,现在不再有用了。

任何想法我做错了什么?(这可能是我忽略的显而易见的事情。)

4

3 回答 3

1

button_to文档在一些地方实际上是错误的(请注意我的回答:为什么这个 button_to 在 Rails 3.2.11 中呈现不正确?)。要修复该提交按钮,请使用以下命令:

<%= button_to "Submit", { action: 'create' }, method: :post %>

和散列需要使用大括号定义明确的分隔符options,具体取决于您要完成的任务。html_options{}

由于HTTP 方法被路由到该操作,因此该create操作不会显示在 URL中。POST/sessioncreate

于 2013-02-08T15:45:41.647 回答
1

到目前为止,Cyle 在上面的评论中建议的方法似乎效果最好,即添加url: session_index_pathsimple_form_for声明中:

<h2>Log in</h2>
<%= simple_form_for :session, url: session_index_path do |f| %>
  <%= f.input :username %>
  <%= f.input :password %>
  <%= button_to "Submit" %>
<% end %>

单击此代码生成的“提交”按钮时,我还没有遇到路由错误。

不过,我不接受这个答案,因为我尚未解决的基本问题是 Rails 的反复无常。也就是说,之前可以运行的代码突然停止运行。例如,今天我首先尝试了这段代码:

<%= simple_form_for :session do |f| %>
  <%= f.input :username %>
  <%= f.input :password %>
  <%= button_to "Submit1" %>
  <%= button_to "Submit2", session_index_path %>
<% end %>

按下“Submit2”按钮有效。但是,当我删除包含按钮“Submit1”的行,停止并重新启动 Rails 服务器(就像我每次尝试之间所做的那样)并重新加载页面时,按下 Submit2 按钮会产生“无路由”错误,甚至尽管按钮的 HTML 代码保持不变:

<form action="/session" class="button_to" method="post">
  <div>
    <input type="submit" value="Submit2" />
    <input name="authenticity_token" type="hidden" value="...this value was the same also..." />
  </div>
</form>

非常令人费解。可能与我的设置细节有关,尽管它不是那么奇特。

编辑时添加:

当我查看由 Cyle 的方法生成的 HTML 的相关部分时,我注意到它与几乎所有其他情况相同:

<form accept-charset="UTF-8" action="/session" class="simple_form session" method="post" novalidate="novalidate">
  <div style="margin:0;padding:0;display:inline">
    <input name="utf8" type="hidden" value="&#x2713;" />
    <input name="authenticity_token" ... />
  </div>
  ...the username and password input fields...
  <form action="/session" class="button_to" method="post">
  <div>
    <input type="submit" value="Submit" />
    <input name="authenticity_token" type="hidden" value="voOGIAbJfwvjxVRbk02V5l6zn6iwvOiMvaeauPBIrqU=" />
  </div>
</form>

所以到目前为止这对我有用可能只是运气。

于 2013-02-11T12:29:39.230 回答
1

问题很可能是在创建应用程序后,我决定更改几个类和相关文件的名称。这导致类名和文件名不符合 Rails 在某些情况下名词复数形式的约定。例如,我有一个文件session_controller.rb,其中包含一个名为SessionController;的类。正确的名称是sessions_controller.rbSessionsController

我创建了一个虚拟 Rails 应用程序,然后命令rails generate scaffold AtUserand rails generate scaffold Session,然后使用生成的文件名和标识符作为更正实际应用程序的指南。现在,我不再收到那些“无路线”错误了。命令rake routes输出:

    at_users GET    /at_users(.:format)          at_users#index
             POST   /at_users(.:format)          at_users#create
 new_at_user GET    /at_users/new(.:format)      at_users#new
edit_at_user GET    /at_users/:id/edit(.:format) at_users#edit
     at_user GET    /at_users/:id(.:format)      at_users#show
             PUT    /at_users/:id(.:format)      at_users#update
             DELETE /at_users/:id(.:format)      at_users#destroy
    sessions POST   /sessions(.:format)          sessions#create
 new_session GET    /sessions/new(.:format)      sessions#new
     session DELETE /sessions/:id(.:format)      sessions#destroy
       login        /login(.:format)             sessions#new
      logout        /logout(.:format)            sessions#destroy
        root        /                            main#index

在此之前,当我在另一个文件中包含一个文件而没有required 前者位于后者的顶部时,我也看到了“无路由”错误。执行重命名修复后,我尝试重现此错误,但它确实再次发生:Rails 错误地报告丢失的路线,而实际问题是缺少require语句。这表明 Rails 的错误报告机制存在缺陷。

感谢用户牛蛙为我指明了正确的方向。

于 2013-02-11T17:02:35.060 回答