Rails_00009
- 格式:pdf
- 大小:1.50 MB
- 文档页数:50
396第30章部署与生产ShippingOption=Struct.new(:id,:name)class ShippingTypeattr_reader:type_name,:optionsdef initialize(name)@type_name=name@options=[]enddef<<(option)@options<<optionendendground=ShippingType.new("SLOW")ground<<ShippingOption.new(100,"Ground Parcel")ground<<ShippingOption.new(101,"Media Mail")regular=ShippingType.new("MEDIUM")regular<<ShippingOption.new(200,"Airmail")regular<<ShippingOption.new(201,"Certified Mail")priority=ShippingType.new("FAST")priority<<ShippingOption.new(300,"Priority")priority<<ShippingOption.new(301,"Express")OPTIONS=[ground,regular,priority]end我们会在视图中创建一个选择列表控件,以便显示辅助模块提供的列表。
这里没有一个高级的包装方法可以方便地创建<select>标签并用分好组的标签填充,所以我们只得改用option_groups_from_collection_for_select()方法——多酷的名字。
该方法的参数包括一个分组的集合、用于获取分组信息与选项信息的访问方法名,以及模型对象的当前值。
我们把这些放在一个<select>标签的内部,该标签的名字是模型对象名和属性名的组合。
下面就是示例代码。
Download e1/views/app/views/test/select.html.erb<label for="order_shipping_option">Shipping:</label><select name="order[shipping_option]"id="order_shipping_option"><%=option_groups_from_collection_for_select(Shipping::OPTIONS,:options,:type_name,#<-groups:id,:name,#<-items@order.shipping_option)%></select>最后,还有一些高级的辅助方法,可以帮助我们方便地创建针对国家和时区的选择列表,请参阅相关的Rails API文档。
日期和时间字段D ate and Time Fieldsform.date_select(:attribute,options)form.datetime_select(:attribute,options)select_date(date=Date.today,options)select_day(date,options)select_month(date,options)select_year(date,options)select_datetime(time=Time.now,options)select_hour(time,options)select_minute(time,options)select_second(time,options)select_time(time,options)用于日期选择的控件有两组。
其中的第一组date_select()和datetime_select()可以创建日1.1Rails是敏捷的397期控件、并使其与ActiveRecord模型对象中类型为date或datetime的属性协作。
第二组日期控件是select xxx的不同变体,它们在没有ActiveRecord支持的情况下也能工作。
下图展示了这些方法的用法。
默认情况下,select_xxx方法生成的HTML控件名称是date[xxx],因此,如果你打算在控制器里获得“分钟”的选择值,只要访问params[:date][:minute]就可以了。
你也可以用:prefix选项更改HTML控件的名称前缀:用:discard_type选项则可以禁止把字段类型放进方括号中;:include_blank选项可以向列表中添加一个为空的选项。
select_minute()方法支持:minute_step=>nn选项。
如果你把这个选项值设为15,列表中就只会出现0,15、30和45这几个选项。
select_month()方法通常会列出每个月的名字作为选项。
如果使用:add_month_numbers=>true选项,就会同时显示每个月的编号:如果使用:use_month_numbers=>true选项,则只显示每个月的编号,不显示名称。
默认情况下,select_year()方法会列出当前年份的前5年和后5年供选择。
你也可以通过:start_year=>yyyy和:end_year=>yyyy选项来改变这一默认设置。
date_select()和datetime_select()方法会创建一个列表框形式的HTML控件,让用户可以设置ActiveRecord模型对象中类型为date(或datetime)的属性值。
@variable.attribute中的日期值会被用作默认值。
在显示的时候,年、月、日(乃至时、分、秒)都会是一个单独的选择列表,用类似:discard_month=>1、:discard_day=>1之类的选项就可以把指定的选择列表去掉。
你只需要设置一个:discard_xxx选项,因为该选项不仅去掉指定单位的选择列表,比其更小的单位也会被一并去掉。
date_select()中各个字段的显示顺序可以用:order=>[symbols,…]选项来指定,其中的symbols参数可以是:year,:month和:day.除此之外,select_xxx支持的所有选项在这里也同样支持。
标签Labelsbel(:object,:method,'text',options)为传递给模板的某个对象(根据:object)的指定属性(根据:method)生成一个label标记。
如果没有明确指定,标签的默认文本是属性的名字。
标签标记的附加的选项可以通过一个hash来传递。
不使用form_for的输入字段辅助方法Field Helpers W ithout Using form_for398第30章部署与生产前面我们己经看到如何在form_for代码块中使用输入字段辅助方法:它们都在传入代码块的表单构建器之上调用。
不过这些方法都有另一个版本,可以在没有表单构建器的情况下使用。
以这种形式使用时,这些方法都必须在第一个参数传入模型对象的名称。
所以,假如action在实例变量中放置了一个User对象:def edit@user=User.find(params[:id])end也可以像这样使用form_for方法。
<%form_for:user do|form|%>Name:<%=form.text_field:name%>...也可以用另一种方式来调用辅助方法:<%form_for:user do|form|%>Name:<%=text_field:user,:name%>...这种风格在生成表单时已经不常用了,不过你还是可能需要用它们来构建由多个ActiveRecord 对象共同组成的表单。
一个窗体,多个模型Multiple Models in a Form到目前为止,我们一直用form_for方法针对单个模型对象创建表单。
如何生成表单来处理两个或更多模型对象的数据呢?form_for方法的一大问题是:它同时做了两件事。
首先,它创建了一个上下文环境(Ruby代码块),表单构建器辅助方法可以在其中生成HTML标签来关联模型属性;其次,它创建了表单所需的<form>标签和相关属性。
这第二件事意味着我们不能用form_for方法来管理多个模型对象,因为那样我们就要在一个页面上放置两个彼此不相关的表单。
fields_for方法会用表单构建器辅助方法来创建上下文环境、并将其关联到模型对象,但不会创建表单。
用这个方法,我们就可以把这个模型对象的字段放进那个对象对应的表单里。
譬如说,货品可能还有一些别的相关信息,通常在货品清单页面上不会显示这些信息。
所以我们不打算把所有这些信息都塞进products表,而是将它们放在details这张附属表里。
Download e1/views/db/migrate/004_create_details.rbclass CreateDetails<ActiveRecord::Migrationdef self.upcreate_table:details do|t|t.integer:product_idt.string:skut.string:manufacturerendenddef self.downdrop_table:detailsendend模型对象也非常简单:Download e1/views/app/models/detail.rbclass Detail<ActiveRecord::Basebelongs_to:productvalidates_presence_of:skuend1.1Rails是敏捷的399视图则使用form_for方法来获取Product模型对象的信息,并在表单内用fields_for来获取Detail模型对象的信息。
Download e1/views/app/views/products/new.html.erb<%form_for:product,:url=>{:action=>:create}do|form|%><%=error_messages_for:product%>Title:<%=form.text_field:title%><br/>Description:<%=form.text_area:description,:rows=>3%><br/>Image url:<%=form.text_field:image_url%><br/><fieldset><legend>Details...</legend><%=error_messages_for:details%><%fields_for:details do|detail|%>SKU:<%=detail.text_field:sku%><br/>Manufacturer:<%=detail.text_field:manufacturer%><%end%></fieldset><%=submit_tag%><%end%>看看这个action生成的HTML代码:<form action="/products/create"method="post">Title:<input id="product_title"name="product[title]"size="30"type="text"/><br/>Description:<textarea cols="40"id="product_description"name="product[description]"rows="3"></textarea><br/>Image url:<input id="product_image_url"name="product[image_url]"size="30"type="text"/><br/><fieldset><legend>Details...</legend>SKU:<input id="details_sku"name="details[sku]"size="30"type="text"/><br/>Manufacturer:<input id="details_manufacturer"name="details[manufacturer]"size="30"type="text"/></fieldset><input name="commit"type="submit"value="Save changes"/></form>请留意针对detail模型对象的字段是如何命名的。