`

表单为什么没有处理方法

阅读更多
在很多Rails2.3的推荐代码中form_for的表单处理,并不写出来提交表单的action

那么,显然,这个Rails的另外的约定了。这个约定是怎么样的规则呢,和Rest有什么关系呢。
例如,如下的代码段(实际是自己生成的)
<% form_for(@lession )do |f| %> 
  <%= f.error_messages %> 
  <p> 
    <%= f.label :name %> 
    <%= f.text_field :name %> 
  </p> 
  <p> 
    <%= f.label :summary %> 
    <%= f.text_field :summary %> 
  </p> 
  <p> 
    <%= f.label :time %> 
    <%= f.date_select :time %> 
  </p> 
  <p> 
    <%= f.label :length %> 
    <%= f.text_field :length %> 
  </p> 
  <p> 
    <%= f.label :content %> 
    <%= f.text_area :content %> 
  </p> 
  <p> 
    <%= f.label :exercise %> 
    <%= f.text_field :exercise %> 
  </p> 
  <p> 
    <%= f.label :means %> 
    <%= f.text_field :means %> 
    <%= f.submit "Update" %> 
  </p> 
<% end %>  


个人查阅form API有下面的看法

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

接下来,这个问题就不是问题了,关键在于这个 FORM 的提交方式。REST 认为:
PUT 表示修改一个既存的资源
POST 表示创建一个新的资源
DELETE 自然表示删除

传统的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 组成的。

link_to "New", new_project_path
=>
<a href="/projects/new">New</a>


这是对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 方法扩展了一下生成的链接,例如:

link_to "Edit", edit_project_path(project)
=>
<a href="/projects/1;edit">Edit</a>


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

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

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


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

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

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

form_for(:project, :url => projects_path) do |f| ...
=>
<form action="/projects" method="post">


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

form_for 方法里的 :html 参数。
form_for(:project, :url => project_path(@project),
:html => { :method => :put }) do |f| ...
=>
<form action="/projects/1" method="post">
<div style="margin:0;padding:0">
<input name="_method" type="hidden" value="put" />
</div>

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

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

link_to "Show", project_path(project)
link_to "Destroy", project_path(project), :method => :delete


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

link_to "Destroy", project_path(project), :method => :delete
=>
<a href="/projects/1"
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</a>


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

以上,部分转载自mypages 应用Rails进行REST 开发

那一系列文章写的不错,值得学习
分享到:
评论
1 楼 xhanxhanxhan 2009-04-15  
一开始也觉得困惑,scaffold的代码new 和edit 基本是一样的。
后来发现rails 会根据 当前对象是否为 new_record? 来生成不同的路径。
很强大,不过对新手也很困惑。

相关推荐

    form表单的异步回调方法

    5. **伪Ajax(Pseudo-AJAX)**:尽管这种异步提交方式不是真正的Ajax(因为没有使用XMLHttpRequest),但它实现了类似的效果,即用户提交表单后,页面不会刷新,而是等待后台的响应。在等待期间,可以显示加载动画或...

    php__表单处理

    请注意,如果表单字段没有值,尝试访问`$_POST`数组元素会得到`NULL`,所以最好进行空值检查: ```php if (isset($_POST['username']) && isset($_POST['password'])) { $username = $_POST['username']; $...

    java Servlet对表单的处理过程

    如果没有,它会创建一个新的Servlet实例,并调用其`init()`方法进行初始化。 4. 服务请求 接着,Servlet容器调用Servlet的`service()`方法来处理请求。`service()`方法会根据请求类型(GET或POST)选择合适的`doGet...

    转义表单提交字符处理函数

    虽然JavaScript中没有直接对应PHP中这些函数的内置方法,但可以通过自定义函数实现类似的功能: 1. **HTML实体编码** - **实现**: ```javascript function escapeHtml(unsafe) { return unsafe .replace(/&/g...

    jsp中在提交表单时的中文处理问题

    在JSP(Java Server Pages)中处理中文字符时,特别是在用户通过表单提交数据时,可能会遇到各种编码问题。这是因为Web应用中涉及到多种编码格式,包括浏览器编码、HTTP请求编码、服务器编码等,如果这些编码不一致...

    表单为JavaBean赋值

    在Java Web开发中,表单数据的处理是一项基础且重要的任务。当用户在网页上填写并提交表单后,这些数据通常需要被转换并赋值到对应的JavaBean对象中,以便于业务逻辑的处理和持久化操作。本教程将详细阐述如何通过...

    隐藏表单方法

    而第二种方法虽然提供了更为稳定的隐藏效果,但在某些场景下可能需要额外的逻辑处理以确保表单状态的正确恢复。 在实际项目中,建议结合具体的使用场景和需求,灵活运用这两种方法。例如,在需要频繁切换界面的情况...

    C# post方式提交Form表单

    在Form表单提交中,POST方法会将表单数据封装在请求体中发送到服务器,而不是像GET那样将其附加到URL后面。这样可以确保数据的安全性,并且对数据长度没有限制。 二、C#实现POST表单提交的步骤 1. 创建HTTP客户端:...

    tomcat过滤器,处理表单提交出现乱码

    当我们处理表单提交时,可能会遇到数据乱码的问题,尤其是在涉及非ASCII字符集(如中文、日文或韩文等)时。这通常与字符编码设置不正确有关。下面,我们将深入探讨这个问题,并提供解决方案。 首先,乱码问题通常...

    jquery实现通过按钮弹出表单

    `$("#popupForm").submit()`则用于处理表单提交,`event.preventDefault()`阻止了表单的默认提交行为,这样我们就可以自定义数据处理逻辑,例如通过Ajax发送数据到服务器。 此外,如果你的表单包含更复杂的交互或...

    防止表单重复提交

    然而,如果没有适当处理,可能会出现表单重复提交的问题,这可能导致数据的不一致性和服务器资源的浪费。本篇文章将深入探讨如何防止表单重复提交,主要关注于基于Struts2框架的解决方案。 首先,理解表单重复提交...

    vue实现重置表单信息为空的方法

    在Vue.js框架中,表单处理是开发过程中常见的任务,其中重置表单信息为空是必不可少的操作。在传统的JavaScript或Vue.js中,我们通常通过手动将表单绑定的数据对象的属性值设为空字符串来实现这一功能。然而,随着...

    phpcms 表单缺失的代码

    "phpcms 表单缺失的代码"这个问题通常是指在安装或使用phpcms时,某些与表单处理相关的代码或者类文件没有正确地被包含或者执行,导致系统功能不完整或者无法正常工作。以下是对这个主题的详细解释: 1. **表单处理...

    Spring In Action SpringMVC 提交表单

    这里,`@GetMapping`方法显示表单,`@PostMapping`方法处理表单提交。 2. 表单模型绑定 `@ModelAttribute`注解用于将HTTP请求参数绑定到Java对象,如User类。SpringMVC会自动将表单字段的值映射到User对象的相应...

    javascript表单处理具体实现代码(表单、链接、按钮)_.docx

    【JavaScript表单处理】在网页开发中,JavaScript是不可或缺的一部分,尤其在处理用户交互和数据提交时。本文将深入探讨JavaScript如何实现表单处理,包括对表单元素(如链接和按钮)的操作。 首先,JavaScript提供...

    jquery实现弹窗表单填写提交

    此外,为了提供更好的用户体验,可以添加表单验证,比如检查输入是否为空,邮箱格式是否正确等,这可以通过jQuery的`val()`方法获取输入值,然后使用正则表达式进行验证。 总结,这个项目涉及了jQuery的基本用法,...

    Servlet表单Get和Post方式读取

    2. **参数值为null**:如果表单字段没有值或者用户没有填写,`getParameter()`会返回`null`,所以需要进行空值检查。 3. **多个相同名字的参数**:对于POST请求,如果表单中有多个同名参数,`getParameter()`只会...

    jquery动态表单

    jQuery的`serialize()`方法可以将表单的所有数据转换为URL编码的字符串,便于发送到服务器。例如: ```javascript var formData = $('#myForm').serialize(); $.ajax({ url: '/submit', data: formData, type...

    学习内容day1------表单的处理

    需要注意的是,GET方法有长度限制,而POST方法没有,因此处理大量数据时通常选择POST。 处理表单数据时,应进行数据验证和清理,防止SQL注入和跨站脚本攻击(XSS)。可以使用`htmlspecialchars()`函数来转义特殊...

    JEECG Online表单对外接口v3.7

    JEECG Online表单对外接口版本v3.7为用户提供了一套详细的接口文档,用于指导如何与JEECG平台进行数据交互。 ### 标题知识点 #### 秘钥配置 秘钥配置是接口安全性的关键,秘钥用于在发送请求时验证发送方的身份。...

Global site tag (gtag.js) - Google Analytics