- 浏览: 273930 次
- 性别:
- 来自: 尤溪
文章分类
最新评论
-
palytoxin:
我现在也发现是这样
关于分享 -
float2net:
Java社区,分享有利于提高。
关于分享 -
hz_qiuyuanxin:
头晕啊,啊邱
RSpec学习笔记 -
reyesyang:
...
关于分享 -
Hooopo:
一般实现map都先实现each
在 Ruby 中对树状结构(tree)进行 map 操作
参考链接:http://guides.rubyonrails.org/form_helpers.html
http://guides.rubyonrails.org/2_3_release_notes.html
http://stackoverflow.com/questions/742536/rails-nested-object-form-attributes-problem
最基本的form helper是form_tag:
没给form_tag传递任何参数的时候,form_tag将生成一个以当前页面为action值,以post为method值的form元素,如下:
这里自动生成了一个隐藏的div,里面有一个隐藏域,name为authenticity_token,value是一个随机字符串,这个隐藏域的值是用于跨站点请求伪造保护(cross-site request forgery protection)的。关于跨站请求伪造。You can read more about this in the Ruby On Rails Security Guide.
form_tag的第一个参数是表单的action值;第二个参数是个hash,可以用来设置表单的method属性和multipart、class等html属性。
rails还提供text_field_tag、label_tag、password_field_tag、hidden_field_tag等常用表单元素的helper,利用这些helper可以组成一个完整的表单。
通常情况下,页面的一个表单是和某个model绑定的,假如用上面这些text_field_tag等带_tag后缀的标签来绑定model,需要为这些helper指定name,示例:
假设这里的@book有属性title='refactor',author='martin fowler'生成的
这里边的重复代码很多,比如book[title]和@book.title。rails提供了更方便的另一系列helper,这些helper不带_tag后缀,如:text_field、text_area。这些helper的第一个参数是model实例变量的名字,第二个参数是model的方法(一般情况下就是model的属性)
这段erb代码和之前的*_tag生成的html差不多。并不是完全一样:
这段erb代码比较之前的干净多了,但是这里还有重复代码:model的名字。rails提供了form_for来消除这个重复:
这段代码也能达到之前的效果,注意这里的text_field等方法是block内参数f的方法。form_for的第一个参数是model的名字,第二个参数是一个model的实例(一般来自controller),如果这个实例的变量名和model名一样,可以把第2个参数省略掉,写成这样:
假如表单中有相关联的其它model的属性,还可以使用fields_for:
fields_for的用法跟form_for差不多,以上代码生成如下HTML:
其中city和street的值可以在controller通过params[:address]取得。
Rails2.3开始支持嵌套的对象表单(Nested Object Form)。在update操作的时候,上面的表单在controller里必须通过@person.address.build(params[:address])来更新address。使用嵌套对象表单可以直接通过@person.update_attributes(params[:person])一句代码来同时完成@person以及@person.address的更新。要使用嵌套对象表单首先要给model添加一句代码,比如这里的Person类:
这里加了一句accepts_nested_attributes_for方法的调用,erb代码可以这样写:
再次注意这里的fields_for,是form_for方法的block里参数f的方法。
生成的HTML:
对比之前的那段HTML,不难发现,这段HTML多了一个隐藏域,用来存放address的id:
同时,city、street输入框的id和name属性和之前也不一样了。比较郁闷的是,Nested Object Form似乎只对update操作有效,create操作就不行,因为在new的页面上得不到address的id,会出现“You have a nil object when you didn't expect it!“。因此,new页面只好使用前面关于fields_for方法的第一个例子中的方式来创建表单了。(仍然有解决的办法:http://www.pixellatedvisions.com/2009/03/18/rails-2-3-nested-model-forms-and-nil-new-record 只要在fields_for之前build_address即可。)
还要注意的是,使用Nested Object Form的时候,form_for的第一个参数不能再是symbol,而必须是一个object,假如使用symbol :person,生成的HTML会变成下面这样:
少了那个隐藏域,而且city和street输入框的id和name属性又不一样了,这样的表单提交之后会出现TypeMismatch Exception。见:http://stackoverflow.com/questions/742536/rails-nested-object-form-attributes-problem
accepts_nested_attributes_for方法的调用会为该类的实例生成一个名为*_attributes=的writer method。详见Rails API中fields_for方法的Nested Attributes Example部分。
最后,RESTful的应用中,对作为资源的model,form_for方法用起来更简单:
这里生成的form元素根据@person的状态来设置action属性:如果@person.new_record?返回true,action中使用的相应的path就是people_path,并且method属性将被设置为post;否则action中使用的相应的path是person_path(@person),并且method属性将被设置为put。再仔细观察,两种情况下form元素的id和class值也会不同:
使用了命名空间(namespace)的resource由于path/url helper与未使用命名空间的resource的path/url helper不同,直接使用form_for(@blog)会找不到blogs_path方法。这种情况下可以这样使用form_for:
这里会自动使用admin_blogs_path或者admin_blog_path(@blog)(视@blog.new_record?的返回值而定),相当于:
或
http://guides.rubyonrails.org/2_3_release_notes.html
http://stackoverflow.com/questions/742536/rails-nested-object-form-attributes-problem
最基本的form helper是form_tag:
<% form_tag do %> Form contents <% end %>
没给form_tag传递任何参数的时候,form_tag将生成一个以当前页面为action值,以post为method值的form元素,如下:
<form action="/books" method="post"> <div style="margin:0;padding:0;display:inline"> <input name="authenticity_token" type="hidden" value="1ZpTUU7D9I2lhajgvAiXlu+JwxujHl4CSfczZWh/aM4=" /> </div> Form contents </form>
这里自动生成了一个隐藏的div,里面有一个隐藏域,name为authenticity_token,value是一个随机字符串,这个隐藏域的值是用于跨站点请求伪造保护(cross-site request forgery protection)的。关于跨站请求伪造。You can read more about this in the Ruby On Rails Security Guide.
form_tag的第一个参数是表单的action值;第二个参数是个hash,可以用来设置表单的method属性和multipart、class等html属性。
rails还提供text_field_tag、label_tag、password_field_tag、hidden_field_tag等常用表单元素的helper,利用这些helper可以组成一个完整的表单。
通常情况下,页面的一个表单是和某个model绑定的,假如用上面这些text_field_tag等带_tag后缀的标签来绑定model,需要为这些helper指定name,示例:
<% form_tag book_path(@book), :method => :put do%> <%= text_field_tag 'book[title]', @book.title %><br/> <%= text_field_tag 'book[author]', @book.author %><br/> <%= submit_tag 'Update' %> <% end %>
假设这里的@book有属性title='refactor',author='martin fowler'生成的
<form action="/books/1" method="post"> <div style="margin:0;padding:0;display:inline"> <input name="_method" type="hidden" value="put" /> <input name="authenticity_token" type="hidden" value="1ZpTUU7D9I2lhajgvAiXlu+JwxujHl4CSfczZWh/aM4=" /> </div> <input id="book_title" name="book[title]" type="text" value="refactor"/><br/> <input id="book_author" name="book[author]" type="text" value="martin fowler"/><br/> <input name="commit" type="submit" value="Update" /> </form>
这里边的重复代码很多,比如book[title]和@book.title。rails提供了更方便的另一系列helper,这些helper不带_tag后缀,如:text_field、text_area。这些helper的第一个参数是model实例变量的名字,第二个参数是model的方法(一般情况下就是model的属性)
<% form_tag book_path(@book), :method => :put do%> <%= text_field :book, :title %><br/> <%= text_field :book, :author %><br/> <%= submit_tag 'Update' %> <% end %>
这段erb代码和之前的*_tag生成的html差不多。并不是完全一样:
<form action="/books/1" method="post"> <div style="margin:0;padding:0;display:inline"> <input name="_method" type="hidden" value="put" /> <input name="authenticity_token" type="hidden" value="1ZpTUU7D9I2lhajgvAiXlu+JwxujHl4CSfczZWh/aM4=" /> </div> <input id="book_title" name="book[title]" size="30" type="text" value="refactor" /><br/> <input id="book_author" name="book[author]" size="30" type="text" value="martin fowler" /><br/> <input name="commit" type="submit" value="Update" /> </form>
这段erb代码比较之前的干净多了,但是这里还有重复代码:model的名字。rails提供了form_for来消除这个重复:
<% form_for :book, @book, :url=>book_path(@book), :html=>{:method=>:put} do |f| %> <%= f.text_field :title%><br/> <%= f.text_field :author%><br/> <%= f.submit 'Update' %> <% end %>
这段代码也能达到之前的效果,注意这里的text_field等方法是block内参数f的方法。form_for的第一个参数是model的名字,第二个参数是一个model的实例(一般来自controller),如果这个实例的变量名和model名一样,可以把第2个参数省略掉,写成这样:
<% form_for :book, :url=>book_path(@book), :html=>{:method=>:put} do |f| %>
假如表单中有相关联的其它model的属性,还可以使用fields_for:
<% form_for :person, :url=>person_path(@person), :html=>{:method=>:put} do |f| %> name:<%= f.text_field :name %><br/> <%fields_for @person.address do |address|%> city:<%=address.text_field :city%><br/> street:<%=address.text_field :street%><br/> <%end%> <%= f.submit 'Update' %> <% end %>
fields_for的用法跟form_for差不多,以上代码生成如下HTML:
<form action="/people/2" method="post"> <div style="margin:0;padding:0;display:inline"> <input name="_method" type="hidden" value="put" /> <input name="authenticity_token" type="hidden" value="hJMxllYlzx0oWi2swhw1Hq3P3yfYMMwL+KXdjOBwXmM=" /> </div> name:<input id="person_name" name="person[name]" size="30" type="text" value="bob" /><br/> city:<input id="address_city" name="address[city]" size="30" type="text" /><br/> street:<input id="address_street" name="address[street]" size="30" type="text" /><br/> <input id="person_submit" name="commit" type="submit" value="Update" /> </form>
其中city和street的值可以在controller通过params[:address]取得。
Rails2.3开始支持嵌套的对象表单(Nested Object Form)。在update操作的时候,上面的表单在controller里必须通过@person.address.build(params[:address])来更新address。使用嵌套对象表单可以直接通过@person.update_attributes(params[:person])一句代码来同时完成@person以及@person.address的更新。要使用嵌套对象表单首先要给model添加一句代码,比如这里的Person类:
class Person < ActiveRecord::Base has_one :address accepts_nested_attributes_for :address end
这里加了一句accepts_nested_attributes_for方法的调用,erb代码可以这样写:
<% form_for @person, :url=>person_path(@person), :html=>{:method=>:put} do |f| %> name:<%= f.text_field :name %><br/> <%f.fields_for :address do |address|%> city:<%=address.text_field :city%><br/> street:<%=address.text_field :street%><br/> <%end%> <%= f.submit 'Update' %> <% end %>
再次注意这里的fields_for,是form_for方法的block里参数f的方法。
生成的HTML:
<form action="/people/2" class="edit_person" id="edit_person_2" method="post"> <div style="margin:0;padding:0;display:inline"> <input name="_method" type="hidden" value="put" /> <input name="authenticity_token" type="hidden" value="hJMxllYlzx0oWi2swhw1Hq3P3yfYMMwL+KXdjOBwXmM=" /> </div> name:<input id="person_name" name="person[name]" size="30" type="text" value="bob" /><br/> <input id="person_address_attributes_id" name="person[address_attributes][id]" type="hidden" value="1" /> city:<input id="person_address_attributes_city" name="person[address_attributes][city]" size="30" type="text" value="sanming" /><br/> street:<input id="person_address_attributes_street" name="person[address_attributes][street]" size="30" type="text" value="xxstreet" /><br/> <input id="person_submit" name="commit" type="submit" value="Update" /> </form>
对比之前的那段HTML,不难发现,这段HTML多了一个隐藏域,用来存放address的id:
<input id="person_address_attributes_id" name="person[address_attributes][id]" type="hidden" value="1" />
同时,city、street输入框的id和name属性和之前也不一样了。比较郁闷的是,Nested Object Form似乎只对update操作有效,create操作就不行,因为在new的页面上得不到address的id,会出现“You have a nil object when you didn't expect it!“。因此,new页面只好使用前面关于fields_for方法的第一个例子中的方式来创建表单了。(仍然有解决的办法:http://www.pixellatedvisions.com/2009/03/18/rails-2-3-nested-model-forms-and-nil-new-record 只要在fields_for之前build_address即可。)
还要注意的是,使用Nested Object Form的时候,form_for的第一个参数不能再是symbol,而必须是一个object,假如使用symbol :person,生成的HTML会变成下面这样:
<form action="/people/2" method="post"> <div style="margin:0;padding:0;display:inline"> <input name="_method" type="hidden" value="put" /> <input name="authenticity_token" type="hidden" value="hJMxllYlzx0oWi2swhw1Hq3P3yfYMMwL+KXdjOBwXmM=" /> </div> name:<input id="person_name" name="person[name]" size="30" type="text" value="bob" /><br/> city:<input id="person_address_city" name="person[address][city]" size="30" type="text" /><br/> street:<input id="person_address_street" name="person[address][street]" size="30" type="text" /><br/> <input id="person_submit" name="commit" type="submit" value="Update" /> </form>
少了那个隐藏域,而且city和street输入框的id和name属性又不一样了,这样的表单提交之后会出现TypeMismatch Exception。见:http://stackoverflow.com/questions/742536/rails-nested-object-form-attributes-problem
accepts_nested_attributes_for方法的调用会为该类的实例生成一个名为*_attributes=的writer method。详见Rails API中fields_for方法的Nested Attributes Example部分。
最后,RESTful的应用中,对作为资源的model,form_for方法用起来更简单:
<%form_for(@person) do |f|%> ..... <%end%>
这里生成的form元素根据@person的状态来设置action属性:如果@person.new_record?返回true,action中使用的相应的path就是people_path,并且method属性将被设置为post;否则action中使用的相应的path是person_path(@person),并且method属性将被设置为put。再仔细观察,两种情况下form元素的id和class值也会不同:
引用
a form creating an article would have id and class new_article. If you were editing the article with id 23, the class would be set to edit_article and the id to edit_article_23.
使用了命名空间(namespace)的resource由于path/url helper与未使用命名空间的resource的path/url helper不同,直接使用form_for(@blog)会找不到blogs_path方法。这种情况下可以这样使用form_for:
<% form_for [:admin, @blog]) do |f|%> ... <% end %>
这里会自动使用admin_blogs_path或者admin_blog_path(@blog)(视@blog.new_record?的返回值而定),相当于:
<% form_for(:blog, @blog, :url=>admin_blogs_path) do |f|%> ... <% end %>
或
<% form_for(:blog, @blog, :url=>admin_blog_path(@blog), :html=>{:method=>:put}) do |f|%> ... <% end %>
评论
3 楼
zhao_j_long
2010-02-23
Very Good! 在使用Nested Form时遇到了问题。
使用Nested Object Form的时候,form_for的第一个参数不能再是symbol,而必须是一个object,假如使用symbo :person,生成的HTML会变成下面这样:
症状吻合,一下解决。非常不引人注意的关键点。
在2.3中可以创建嵌套对象吧。
使用Nested Object Form的时候,form_for的第一个参数不能再是symbol,而必须是一个object,假如使用symbo :person,生成的HTML会变成下面这样:
症状吻合,一下解决。非常不引人注意的关键点。
在2.3中可以创建嵌套对象吧。
2 楼
yuan
2009-09-28
之前看滑板书学得迷迷糊糊的,还是guides讲得清楚。
1 楼
机器人
2009-09-28
不错,有钻研精神
发表评论
-
rails测试中遇到的一些问题
2010-09-03 11:41 25081,页面的测试。 假设某view中有一个表单,表单里有3个字段 ... -
BDD on Rails
2010-05-11 02:59 0首先,嘿嘿,我对敏捷 ... -
强大的 Rails 2 查询、搜索插件:SearchLogic
2010-04-20 23:31 5423发现还有人在看这个博客,这个 SearchLogic 只支持 ... -
authlogic-openid
2010-04-20 00:32 0http://github.com/binarylogic/a ... -
测试驱动开发实战(authlogic学习笔记)
2010-04-17 00:06 0这会是个很cool的笔记 cucumber还不会用,只用R ... -
RoR简单培训。
2010-04-12 10:08 0目的 上周二Bob给大家从总体上概括了一下Rails的开发。我 ... -
用RSpec和Webrat为页面写测试
2010-03-10 23:26 0The RSpec Book 23章(不完全照书上记,而是我自 ... -
rails杂记
2010-03-08 11:36 1422=======Rails2======= 用RSpec测试A ... -
Rails文件上传利器——paperclip笔记
2010-02-27 12:04 14928Githubhttp://wiki.github.com/th ... -
为SearchLogic添加一个remote_form_for方法。
2010-02-10 15:00 1377稍微看了一下,好像挺简单,只是处理了一下参数。 # A ... -
A Guide to Testing Rails Applications
2010-02-03 19:56 0什么是Fixtures fixtures允许你在测试运行之前往 ... -
改个bug
2010-01-20 17:38 1205问题见:http://yuan.iteye.c ... -
reset/reload
2010-01-20 16:26 1125http://caboo.se/doc/classes/Act ... -
Acts As Taggable On Steroids
2010-01-20 13:53 2593参考着mephisto写blog程序 ... -
Active Record Validations and Callbacks
2009-10-18 02:45 2360参考链接:http://guides.ru ... -
Layout in Rails
2009-10-12 17:28 4730参考链接:http://guides.rubyonrails. ... -
Rendering in Rails
2009-10-10 02:10 4509参考链接:http://guides.rubyonrails. ... -
如何为Rails的views写测试。
2009-10-01 16:53 1107原文链接:http://weblog.jamisbuck.or ... -
rails2.3 routes笔记
2009-09-23 04:10 2821参考链接:http://guides.ru ... -
rails中分模块开发。
2009-09-18 14:48 2298我没事就喜欢拿blog练手,blog简单嘛。 嗯,其实这是 ...
相关推荐
npm install --save react-rails-form-helpers 通过供应商使用 您可以从获取最新的UMD版本。 关于 该软件包提供了用于编写针对Rails的表单的组件。 该软件包的主要目的是用于通过命名组件传达表单的目的。 如果您对...
最后,书中还介绍了Rails中的表单构建器(Form Builder),渲染器(Renderer)和railties辅助工具(Helpers)。Rails的表单构建器简化了表单创建过程,渲染器则用于将数据渲染为不同的视图格式,而railties则是Rails...
- 帮助器(Helper):定义在`app/helpers`,提供视图中重用的函数。 - 组件(Partial):如`_form.html.erb`,部分视图,用于代码复用。 - 资源路由(Resourceful Routing):通过`resources :posts`,自动创建CRUD...
使用 ActiveRecord 提供的安全功能,如 strong parameters 和 form helpers 可以帮助提高安全性。 提供的压缩包文件 `rails.exe` 看起来是一个可执行文件,可能是一个预打包的 Rails 应用程序,包含了上述登录功能...
随着你深入学习,你将了解到更多关于ActiveRecord、辅助方法(helper methods)、部分视图(partials)、表单构建(form helpers)、认证和授权(如Devise和Pundit)以及部署到服务器(如Heroku)的知识。Rails社区...
# app/helpers/application_helper.rb module ApplicationHelper def custom_js_function(name) "<script>#{name}</script>".html_safe end end # views/layouts/application.html.erb ('Hello, world!')" %> ``...
- **Form helpers**: 使用Rails内置的表单辅助方法创建HTML表单。 - **AJAX和Unobtrusive JavaScript (UJS)**: 在Rails中实现异步更新和无刷新交互。 - **部署**: 如何将Rails应用部署到Heroku或AWS等云平台。 通过...
app / helpers / application_helper.rb- setup_search_form ,它使用分组模板创建一个Javascript搜索对象,因为我们不能在Ruby中动态创建分组模板(分组可以包含其他分组,最终会无限递归)。 这里的其余方法与...
Rails 还提供了许多辅助方法,如 `link_to`、`form_for` 等,帮助简化视图代码。 9. **测试驱动开发(TDD)**:Rails 鼓励使用测试驱动开发,为此提供了 RSpec 和 MiniTest 等测试框架。开发者可以编写测试确保代码...
2. **表单帮助器(Form Helpers)**: 在嵌套表单中,`fields_for`是关键的辅助方法。它允许在主表单中包含一个关联模型的字段,这样用户就可以同时创建或编辑两者。例如,`form_for @post do |f|`内可以添加`f....
Rails提供了一系列视图助手方法,如`link_to`、`form_for`等,帮助简化视图代码。在`Travel-app`中,开发者可能使用`link_to`创建导航链接,`form_for`创建表单来提交新目的地或标签。 9. **Bootstrap或自定义CSS*...
- `app`包含了模型(models)、控制器(controllers)、视图(views)以及助手方法(helpers)。 - `config`存放应用的配置文件,如数据库配置、路由配置等。 - `db`用于数据库相关,包括数据库迁移(migrations...