Rails中文Podcasts【四】

一、HABTM CheckBoxes

首先解释一下什么是HABTM即HasAndBelongsToMany,这个是ActiveRecord里面很有意思也是比较复杂的一下东西,在SNS领域里面有很大作用。

在这个例子中我们用到了两个models,Product和Category,两个互有有has_and_belongs_to_many的关系,我们会通过一个form_for表单中的checkboxes来编辑product所属的category。

添加checkboxes

The edit form with the checkboxes added.

如图所示,我们已经有一个表单了,但是还没有分类用的checkboxes。这里介绍两种添加checkboxe到form表单的方法,一个是check_box,一个是check_box_tag。我们先用check_box_tag,加到这个edit form表单中(products/edit.html.erb)

<% for category in Category.find(:all) %>
    <div>
      <%= check_box_tag "product[category_ids][]", category.id, @product.categories.include?(category) %>
      <%= category.name %>
    </div>
<% end %>
check_box_tag接收了三个参数,checkbox的名字,checkbox的值和一个决定它是否被选中的boolean值。

来看一下是不是工作了

The edit form with the checkboxes added.

我们点一下,然后提交,然后就可以工作了,在我们提交的时候其实提交了这样一些数据

Processing ProductsController#update (for 127.0.0.1 at 2009-01-15 20:57:56) [PUT]
Parameters: {"commit"=>"Edit", "authenticity_token"=>"31b711f2c24ae7cea5abf3f758eef46b472eebf3", "product"=>{"price"=>"99.0", "name"=>"Television Stand", "category_ids"=>["2", "4"]}, "id"=>"1"}

其中"category_ids"=>["2", "4"]就是重点啦,在product的controller中update里面什么都还没加,你可能会奇怪为什么这里传了个数组类就被分好了吧,
其实rails在背后帮我们把这个地方给做了,它是根据我们的has_and_belongs_to_many方法来生成了一个方法"category_ids",同时根据params里面的传来的东西把这个属性自动更新了,当然也可以自己做这个事情,具体的做法就是根据这个数组去对应的category,然后调用category的push方法把product给push进去。

给一个小提示

当你把checkboxes里面的都不选中的时候,提交会发生一些奇怪的事情,那就是在params里面不会传"category_ids"这个参数,在update里面就不会更新这个属性了,所以我们需要人为的在这里家一个语句

params[:product][:category_ids] ||= []
这样就不会发生当你不check一个checkbo的时候数据没有更新的情况了。

如何在Android客户端上提交这份表单呢

但是当你需要用Java发送一个类似的请求的时候,你可能需要用到Java中的BasicNameValuePair来传递一些参数,但是使用BasicNameValuePair只能传键值对,而值只能是string,不能是数组,所以我在这里想到一种解决办法,那就是往BasicNameValuePair中的value存"2,4,5",这个时候当你POST这个请求的时候,rails就能接受到你需要的参数了,还没完,因为category_ids在被rails存到数据库的时候只能是数组,所以我们到product#controllrt#update方法里面加上和上面小提示类似的东西

params[:product][:category_ids] = params[:product][:category_ids].split(‘,')

这样,我们借助split方法就把一个string变成了rails想要的数组了。

二、循环遍历Flash

有时候我们的页面布局会因为过多的flash信息而变得很局促,每段用来检查message是否为空的代码都会占用很多行,我们可以使用这样的代码来处理

<% flash.each do |key,msg| %>
  <%= content_tag :p, msg, :id => key %>
<% end %>

其中content_tag接收三个参数:第一个是元素的名字;第二个是这个元素开始和结束之间的内容(映射到html中的内容);第三个是一个可选的标记元素属性的hash。

三、一个可以hold住宇宙的routes是什么样子?

我也不太清楚从什么时候开始,rails的routes.rb取消了map的做法,以前的map.connect方法却是对应现在的match方法,在你的routes.rb中添加这样一句

 match '*path', :controller => 'redirect', :action => 'index'

当然,你需要rails generate controller redirect 一个新的controller来做这样一件事情,现在,凡是在routes.rb中找不到的路径统统都会被丢给redirect controller了,同时会把相应的路径变量赋给path变量,比如http://localhost:3000/xxoo以后就是{"path" => ["xxoo"]},params[:path]的值为xxoo了。

你当然可以利用这里的path值来做查询和其他的事情,然后,如果你想做一个淘宝的推广连接,现在是不是会突然有些灵感了?


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值