十二 30

Rails Rdoc笔记:respond_to

首先祝所有的朋友09年工作学习顺利。祝李猪猪小朋友即将到来的幼儿园生活开心。

刚才看了下respond_to这个方法,想写上一些东西。

最新做的项目,要求松耦合。因为之前2个月一直在做康盛的uchome的项目设计,对这种设计方式有点自己的想法。所以在初级设计这个代号kx2009的Rails项目时,走了些弯路。刚才看到redpond_to的文字,感觉又回到了一个正确使用Rails的方向,就是更加的REST,要web service。

REST的概念在我心里是来做资源管理的,这个资源管理要简单,所以我并不喜欢/users/1/posts/22这种资源嵌套,我更喜欢是/users/1,而他的posts就是/posts/index,/posts/22,足够。

多态。这次用到了很多多态的方法,使得设计上每个部分都很松耦合,能够复用,比如那个photos,就可以给活动,圈子,论坛去承担不同Model的图片上传,显示,管理功能。积分和信誉积分采用了同样的设计,下面的Account就是多态。(不过自动累加上一个Model的total字段稍微麻烦了点,magic有类似counter_cache的功能吗?对belongs_to那方的total字段进行自动加减?)

好了,看看Rdoc的描述。大意是:Rails是一个很好的web-service框架。

Without web-service support, an action which collects the data for displaying a list of people might look something like this:

  def index
    @people = Person.find(:all)
  end

Here‘s the same action, with web-service support baked in:

  def index
    @people = Person.find(:all)

    respond_to do |format|
      format.html
      format.xml { render :xml => @people.to_xml }
    end
  end

What that says is, "if the client wants HTML in response to this action, just respond as we would have before, but if the client wants XML, return them the list of people in XML format." (Rails determines the desired response format from the HTTP Accept header submitted by the client.)

Supposing you have an action that adds a new person, optionally creating their company (by name) if it does not already exist, without web-services, it might look like this:

  def create
    @company = Company.find_or_create_by_name(params[:company][:name])
    @person  = @company.people.create(params[:person])

    redirect_to(person_list_url)
  end

Here‘s the same action, with web-service support baked in:

  def create
    company  = params[:person].delete(:company)
    @company = Company.find_or_create_by_name(company[:name])
    @person  = @company.people.create(params[:person])

    respond_to do |format|
      format.html { redirect_to(person_list_url) }
      format.js
      format.xml  { render :xml => @person.to_xml(:include => @company) }
    end
  end

If the client wants HTML, we just redirect them back to the person list. If they want Javascript (format.js), then it is an RJS request and we render the RJS template associated with this action. Lastly, if the client wants XML, we render the created person as XML, but with a twist: we also include the person‘s company in the rendered XML, so you get something like this:

  <person>
    <id>...</id>
    ...
    <company>
      <id>...</id>
      <name>...</name>
      ...
    </company>
  </person>

Note, however, the extra bit at the top of that action:

  company  = params[:person].delete(:company)
  @company = Company.find_or_create_by_name(company[:name])

This is because the incoming XML document (if a web-service request is in process) can only contain a single root-node. So, we have to rearrange things so that the request looks like this (url-encoded):

  person[name]=...&person[company][name]=...&...

And, like this (xml-encoded):

  <person>
    <name>...</name>
    <company>
      <name>...</name>
    </company>
  </person>

In other words, we make the request so that it operates on a single entity‘s person. Then, in the action, we extract the company data from the request, find or create the company, and then create the new person with the remaining data.

Note that you can define your own XML parameter parser which would allow you to describe multiple entities in a single request (i.e., by wrapping them all in a single root node), but if you just go with the flow and accept Rails’ defaults, life will be much easier.

If you need to use a MIME type which isn‘t supported by default, you can register your own handlers in environment.rb as follows.

  Mime::Type.register "image/jpg", :jpg
  • 标签 : 
  • 原文链接 : http://railser.cn/blog/rails-rdoc-respond_to
  • 转载原创文章请注明 : 里克的自习室
  • 收藏到 : Google书签 新浪ViVi 365Key网摘 天极网摘 我摘 POCO网摘 博采网摘 YouNote网摘 和讯网摘 博拉网 igooi网摘 I2Key网摘 天下图摘 百特门网摘 Del.icio.us Yahoo书签 奇贴 QQ娱乐摘 添加到Digg! 添加到Facebook!
  •  “Rails Rdoc笔记:respond_to”才1条评论

    1. gravatar

      自動加減似乎沒法做到
      只能用:
      increment!, decrement!, update_counter
      來做了

    发表留言