「已注销」 2009-04-24 12:04
浏览 283
已采纳

form_tag中点击submit时Unknown action错误

具体是这样的。
我在做一个项目时建立了一个management的controller(没有使用手脚架生成),里面有index方法
management的视图中有一个index.html.erb
而index.html.erb中调用了模版 <%= render(:partial => admin ) %>
而_admin.rhtml模版文件中我又调用了模版<%= render(:partial => usermanage) %>
在_usermanage.rhtml模版文件中有一段代码如下:
<% form_tag :action=>'index', :conrtoller=>management do -%>
<%= submit_tag "Search" %>
<% end %>

问题是每次点击submit按钮时就会出现Unknown action错误,究竟是怎么回事啊?是不是因为多重模版套用所以找不到方法啊?有没有什么解决办法啊?我都试了好久了~~~~
[b]问题补充:[/b]
哦,不好意思。上面是我写漏了一个冒号,那段代码确实是
<% form_tag :action=>'index', :conrtoller=>:management do -%>
<%= submit_tag "Search" %>
<% end %>

他提示的错误具体是如下:
Unknown action
No action responded to create. Actions: access_denied, admin, check_roles, convert_to_base, convert_to_base16, convert_to_base_old, cs, hex_to_str, index, orderinfo, ordermanage, prizeinfo, prizemanage, redemptioninfo, role_requirements, role_requirements=, topupinfo, and usermanage

[b]问题补充:[/b]
我现在修改成下面那样就暂时解决了~
<% form_tag '/management', :method=>'get' do -%>
<%= submit_tag "Search" %>
<% end %>
页面可以顺利跳转,而且运行index方法。但实在不明白为什么会这样。如果我要点击按钮运行management控制器的其他方法呢?

本人是第一次接触rails,总是遇到Unknown action错误,好郁闷啊~~~

  • 写回答

3条回答 默认 最新

  • horace_lee 2009-04-24 14:19
    关注

    那么,你的rails是2.3了对吧
    这是REST调用的问题

    参考下面内容吧

    我的建议是,你先大概看看REST

    首先要了解的是 REST 的概念,然后需要了解 Rails 对 REST 的理解。

    接下来,这个问题就不是问题了,关键在于这个 FORM 的提交方式。REST 认为:
    PUT 表示修改一个既存的资源
    POST 表示创建一个新的资源
    DELETE 自然表示删除
    [img]http://mypages.iteye.com/upload/picture/pic/28467/1210821d-9e34-3c63-9016-7dba325191af.jpg[/img]
    传统的link_to 所生成的链接中包含了controller和action,相对比,使用新的 “project_path” 所创建的链接,只包含了controller 和 资源的id –毫无疑问,这是一个 REST风格的URL。因为链接默认的是一个“Get”请求,Rails 能够知道这一点,所以就会去调用 show action。对于每一个资源,rails 都会有7个标准的 path 方法,这些可以从表1.2中看到。

    每一个path 方法都关联一个 http 协议的动作,一些请求(例如show,create),可以通过http协议的 Get 或 Post 传递给服务器;但是有一些请求,如 update,delete,则需要一些其他的方式(如使用隐藏的变量)传递给服务器,因为浏览器并不知道 PUT和DELETE动作。接下来的章节我们会仔细的介绍。

    进一步看看这个表,我们也会发现4个http 动作,并不足以包含全部的CRUD操作。前2个方法使用Get的方式会工作的很好,但是对于new_project_path 和 edit_project_path 就不同了。

    New 和 Edit
    用户如果点击一个“新建”链接,那么会使用Get动作来对服务器发送一个请求。下面的例子表明,生成的链接是由 controller 和一个“new”action 组成的。

    [code="ruby"]link_to "New", new_project_path
    =>
    New[/code]

    这是对REST思想的一种破坏?或许乍看之下确实如此。但是如果你仔细看,那么一切都会清晰,“new”并不是一个CURD的action,它更像一个建立一个新的资源之前的准备的动作。真正的CRUD 中的create被调用,是在新的form被提交的以后才执行的。这个链接当然也没有资源的id—因为资源还没有被创建。一个链接如果没有资源的id,那么就不应该被称为REST的URL,因为REST的URL总是会指定一个资源的id。所以,这个 “new” action 仅仅因该用来显示一个新的form的页面而已。

    对于 edit_project_path ,也是同样的道理。它引用了一个资源,但是仅仅是在调用 update action 之前的准备工作。真正的update action 是在页面被提交以后才执行的。edit_project_path 和 new_project_path 唯一的区别就是前者需要使用一个资源的id。按照REST的规则,资源的id放在controller 的后面:/project/1 。但是如果仅仅使用Get 动作来提交这个URL,那么Rails将会认为你要调用的是show action。为了防止这一点,edit_project_path 方法扩展了一下生成的链接,例如:

    [code="ruby"]link_to "Edit", edit_project_path(project)
    =>
    Edit[/code]

    这样,我们就能理解为什么允许 edit_project_path 和 new_project_path生成的链接里带有 action 了,因为他们两个都不是REST的 CRUD URL,他们仅仅是准备工作。还有其它的一些URL和这两个很相似,我们会在后面的章节介绍。

    在 form 中使用 path 方法:Create 和 Update
    传统的方式上,我们使用 form_tag 或 form_for 来创建一个form:

    [code="ruby"]<% form_for :project, @project, :url => { :action => "create" } do |f|
    %>
    ...
    <% end %>[/code]

    在REST应用中,这个 :url hashmap 会被 path 方法给取代:

    “project_path” 创建新的资源所使用的form
    “project_path(:id)”编辑一个资源所使用的form

    a) 创建资源所使用的form
    form 使用 post 动作向服务器提交信息,“project_path”方法并不会有资源id作为参数,这样,生成的URL就应该是“/projects”这个样子。当提交到服务器以后,就会调用 create action。

    [code="ruby"]form_for(:project, :url => projects_path) do |f| ...
    =>

    [/code]

    b) 编辑一个资源所使用的form
    按照REST的思想,一个更新的操作是使用http协议的PUT动作来发送的。但是,正如我们所知道的,浏览器只明白 Post和Get动作。解决的办法就是使用

    form_for 方法里的 :html 参数。
    [code="ruby"]form_for(:project, :url => project_path(@project),
    :html => { :method => :put }) do |f| ...
    =>

    [/code]
    Rails 生成了一个隐藏的字段来代替http的put 动作。提交以后,Rails 会检查这个变量,然后判断是否去调用update方法。

    删除
    恐怕我们已经发觉了,用于显示和删除一个资源,所使用的path方法都一样:

    [code="html"]link_to "Show", project_path(project)
    link_to "Destroy", project_path(project), :method => :delete[/code]

    唯一的不同就是 删除的时候,使用了一个变量 :method,用它来表示http的DELETE动作。因为浏览器不支持DELETE动作,所以,Rails 会生成一些javascript来解决这个问题:

    [code="js"]link_to "Destroy", project_path(project), :method => :delete
    =>
    onclick="var f = document.createElement(’form’);
    f.style.display = ’none’; this.parentNode.appendChild(f);
    f.method = ’POST’; f.action = this.href;
    var m = document.createElement(’input’);
    m.setAttribute(’type’, ’hidden’);
    m.setAttribute(’name’, ’_method’);
    m.setAttribute(’value’, ’delete’); f.appendChild(m);f.submit();
    return false;">Destroy
    [/code]

    这段javascript 会生成一个form,把 http 的DELETE动作放在隐藏变量里传递给服务器,然后,Rails 会判断这个变量,决定是否去调用destroy 方法。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 基于卷积神经网络的声纹识别
  • ¥15 Python中的request,如何使用ssr节点,通过代理requests网页。本人在泰国,需要用大陆ip才能玩网页游戏,合法合规。
  • ¥100 为什么这个恒流源电路不能恒流?
  • ¥15 有偿求跨组件数据流路径图
  • ¥15 写一个方法checkPerson,入参实体类Person,出参布尔值
  • ¥15 我想咨询一下路面纹理三维点云数据处理的一些问题,上传的坐标文件里是怎么对无序点进行编号的,以及xy坐标在处理的时候是进行整体模型分片处理的吗
  • ¥15 CSAPPattacklab
  • ¥15 一直显示正在等待HID—ISP
  • ¥15 Python turtle 画图
  • ¥15 stm32开发clion时遇到的编译问题