在Rails3的controller中,很明显的一个变化就是respond_to不见了,取而代之的是respond_with这个方法,那么这个新的方法有什么好处呢?下面是我的一次小小的初探经历。
生成代码之后启动服务器,访问对应的url,我得到了一个这样的错误。
In order to use respond_with, first you need to declare the formats your controller respon
程序告诉了我应该为action的返回类型做一个声明,不然rails不知道该返回哪种格式的数据,好吧,我在controller的类级别添加了如下声明
respond_to :html
然后刷新浏览器,现在可以正常访问页面了。继续写代码。。。。
突然,我觉得我的程序应该支持多种数据类型的返回,如支持xml, json等格式。这时我在浏览器中键入 /posts/1.xml ,于是我得到了这样一个错误。
This page contains the following errors: error on line 1 at column 1: Extra content at the end of the document Below is a rendering of the page up to the first error.
为了修正它,我只需要在刚才添加的代码上多加上一个参数即可
respond_to :html, :xml, :json
现在,我的这个controller中所有的action都支持这3种格式了,是不是比在rails2中的每个action中都写format.html, format.xml等方便多了。观众举手发问:“如果我只想在index中接受html格式,但在show中接受json格式怎么办?”,哈哈,Rails3也为我们想到了这个问题,respond_to方法可以和before_filter方法一样接受only和except方法,与此同时respond_with也接受block的书写方式,这样你就可以随心所欲的定制格式了。
好,继续往下。如果你足够细心,你就会发现以前十几行代码量的create变的只有5行了。如下
def create @post = Post.new(params[:post]) flash[:notice] = 'Post was successfully created.' if @post.save respond_with(@post) end
经过对比发现这主要是respond_with的功劳,它只用一行代码就担起了redirect_to(数据保存正确)和render(数据验证失败)的两个任务。当数据保存成功后,它自动跳转到@story对应的显示页面,当保存失败后,会自动render的@story的new页面。(同样,在updated中会分别对应着show和edit两个action) 到这,我彻底的又佩服了一次rails的进一步改进。可代码写着写着,问题又来了。
现在我有这样一个controller,文件位于admin/post_controller.rb,它已经不是位于app/controllers的顶级目录了,问题就出在这。我还是用默认的代码去进行一系列操作,当数据保存成功后,它跳转到了hosts/posts/1这个链接,而不是对应的http://host/admin/posts/1,究其原因,是因为我们在create的代码中采用默认@post的路径,默认@story是对应story_path(@story)的,而我们想用的是admin_story_path(@story),幸好,rails也给我们留出了扩展。
# in create or update respond_with(@post, :location => admin_post_url(@post))
呵呵,代码还是那么简单。