`

rails3之ActionController

    博客分类:
  • ruby
阅读更多
rails3中有许多变化,现在也只能看一点说一点了,趁现在还有点心情,赶快把它整理写下来。
对于ActionController来说,一个比较明显的改进就是对respond_to的处理,这主要涉及到REST方面的处理。
比如在rails2中:
def index
    @users = User.all

    respond_to do |format|
      format.html # index.html.erb
      format.xml  { render :xml => @users }
    end
end

在rails3中则可以进行简写:
def index
    @users = User.all
    respond_with(@users)
end

当然还要在application_controller.rb中加句代码:
class ApplicationController < ActionController::Base
  respond_to :html, :xml
  protect_from_forgery
end

从rail2.3开始,protect_from_forgery默认便是开启状态。至于此代码的作用以前也没在意,在网上找了一下:
引用

protect_from_forgery - A feature in Rails that protects against Cross-site Request Forgery (CSRF) attacks. This feature makes all generated forms have a hidden id  field. This id field must match the stored id or the form submission is not accepted. This prevents malicious forms on other sites or forms inserted with XSS from submitting to the Rails application.

当然有些方法会麻烦点:
def create
    @user = User.new(params[:user])

    respond_to do |format|
      if @user.save
        format.html { redirect_to(@user, :notice => 'userwas successfully created.') }
        format.xml  { render :xml => @user, :status => :created, :location => @product }
      else
        format.html { render :action => "new" }
        format.xml  { render :xml => @user.errors, :status => :unprocessable_entity }
      end
    end
  end

这个方法处理起来就要麻烦一点了:
   def create
    @user= User.new(params[:user])
    respond_with(@user) do |format|
      if @user.save
        flash[:notice] = "userwas created successfully."
        format.html { redirect_to @user}
      else
        format.html { render :action => :new }
      end
    end
  end

因为验证通过才创建对象,否则返回原来创建的页面并显示相应的错误信息。这个地方有个小问题,那就是通过REST的方式来操作即以xml的方式请求时,返回不了相应的错误信息。
而且上面的方法并没有简化多少,毕竟输出xml或html格式的代码大多都是可重复利用的,因此rails可以做得更好,rails3的确做到了,那就是ActionController::Responder,这个类完美的解决了输出格式的问题。此类文档里面有说明:
引用

# Using Rails default responder, a POST request for creating an object could
  # be written as:
  #
  #   def create
  #     @user = User.new(params[:user])
  #     flash[:notice] = 'User was successfully created.' if @user.save
  #     respond_with(@user)
  #   end
  #
  # Which is exactly the same as:
  #
  #   def create
  #     @user = User.new(params[:user])
  #
  #     respond_to do |format|
  #       if @user.save
  #         flash[:notice] = 'User was successfully created.'
  #         format.html { redirect_to(@user) }
  #         format.xml { render ml => @user, :status => :created, :location => @user }
  #       else
  #         format.html { render :action => "new" }
  #         format.xml { render ml => @user.errors, :status => :unprocessable_entity }
  #       end
  #     end
  #   end

因此创建方法将变得非常的简单:
  def create
    @user  = User.new(params[:user])
    flash[:notice] = 'User was successfully created.' if @user.save
    respond_with(@user,:location=>users_url)
  end

当然这个方法简化了很多,似乎有些神奇,主要过程就是通过respond_with调用ActionController::Responder内部相应的方法,然后。。,然后该干嘛干嘛,就不用管了。rails里面就是有这么多神奇的地方,要明白其中的原理就有些高深了,反正读rails源码要比读java框架的源码难得多,因为封装得太深了。
如果要手动控制跳转的路径可以这样:
  def create
    @user = User.new(params[:user])
    flash[:notice] = "User was created successfully." if @user.save
    respond_with(@user) do |format|
      format.html { redirect_to users_url }
    end
  end

当然更简单的方式是这样的:
  def create
    @user = User.new(params[:user])
    flash[:notice] = "User was created successfully." if @user.save
    respond_with(@user, :location => users_url)
  end

也就是说redirect_to大概与location的作用差不多。上面这段代码中users_url是一个比较有意思的东西,现在还不能很好解释清楚,虽然没有明确的定义,但它确实是有值的,上面代码的意思表示创建一用户成功后跳转到显示整个users列表的页面,即./users页面。如果不要那个:location=>users_url,则会跳转到显示显示单个user的页面。如果要细究的话,这个respond_with是处理方式还是很复杂的,看着别人用不会有问题,如果稍微变一下就会有问题。主要是用来处理rest的数据交互,不然的话直接用redirect_to,这个方式就不那么让人困惑。
当然respond_with也有:status与:head等属性。比如:
 def destroy
    @product = Product.find(params[:id])
    @product.destroy

    respond_to do |format|
      format.html { redirect_to(products_url) }
      format.xml  { head :ok }
    end
  end

可以写成:
  def destroy
    @product = Product.find(params[:id])
    @product.destroy
    respond_with(@product,:location=>products_url,:head => :ok)
  end

不过有个问题,在IE7中删除这个功能居然不能用,应该是JS的问题,在Firefox没什么问题,由于开始测试的时候用的时IE7,让本人郁闷了不少时间。
现在想想可能是html5,rails3好像采用了html5的特性,IE7怎么可能支持呢?

这篇文章只是简单的介绍了一下respond_with,如果要想知道这些action的跳转方式及跳转原理的话,那又会是一个相当麻烦的话题,涉及的内容很多。同时在rails3中也有比较大的变化,总之rails的URL跳转封装得太深,虽然用起来很方便,但理解起来却比较困难。

最近发现别看着rails有许多强大的特性,但如果要明白它的实现原理的话,还是非常复杂的,可能比java还要复杂得多,毕竟struts,spring,hibernate实现机制相对来说容易理解一些,java框架的实现总体来说是比较平滑的,而rails则不同,里面有很多激进的方式,跨度很大,而且版本变更也很大,理解起来要困难得多。
参考文章:
http://weblog.rubyonrails.org/2009/8/31/three-reasons-love-responder
http://blog.plataformatec.com.br/2009/08/embracing-rest-with-mind-body-and-soul/
http://ryandaigle.com/articles/2009/8/6/what-s-new-in-edge-rails-cleaner-restful-controllers-w-respond_with/
分享到:
评论

相关推荐

    Rails 3 in Action

    3. **MVC架构**:Rails采用Model-View-Controller架构,书中详细解释了模型(Model)、视图(View)和控制器(Controller)之间的交互与职责。 4. **路由**:Rails的路由系统允许灵活地定义URL到控制器动作的映射,...

    Rails 4 in Action, Second Edition.pdf

    - **MVC架构**:Rails采用了经典的Model-View-Controller架构,其中模型负责处理业务逻辑,视图负责显示界面,控制器则作为二者之间的桥梁。 - **Active Record**:这是Rails提供的ORM(对象关系映射)解决方案,...

    Beginning Rails 3

    3. **模块化**:Rails 3将框架分解成多个可独立使用的组件,如ActiveRecord、ActionController等,这使得开发者可以根据项目需求选择性地使用这些组件。 4. **与Ruby 1.9的兼容性**:Rails 3全面支持Ruby 1.9,这...

    live-stream:Rails 4 ActionController Live Stream 演示简单的聊天应用程序

    使用 Rails 4 的简单聊天应用程序 - ActionController::Live 应用组件: 1 . 使用 Rails 4 ActionController::Live 的聊天应用程序 2 . 基本 LDAP 身份验证 3 . Redis 服务器集成 4 . 彪马服务器 1 . Rails 4 ...

    Rails

    3. **Action Controller**:负责处理HTTP请求并调用模型来执行业务逻辑,然后将结果传递给视图进行渲染。 4. **Action View**:用于生成HTTP响应的视图层,可以使用ERB(嵌入式Ruby)或其他模板引擎来创建HTML输出。...

    rails2-sample

    此外,Rails还内置了许多实用功能,如ActiveRecord(用于数据库交互)、Action View(用于页面渲染)和Action Controller(用于处理用户请求),这些都使得开发者能够快速构建出功能丰富的Web应用程序。 #### 2. ...

    rails指南 中文版

    2. **ActionController**:负责处理HTTP请求并生成HTTP响应。控制器是MVC架构中的C,它连接模型和视图,处理用户输入,调用模型进行业务逻辑处理,并将结果传递给视图进行展示。 3. **ActionView**:视图部分用于...

    Ruby-MongoModel针对MongoDB的RubyORM框架兼容Rails3

    9. **兼容性**:MongoModel兼容Rails 3,意味着它可以与其他Rails组件如ActionController和ActiveSupport无缝协作,提供完整的Web应用开发体验。 在"spohlenz-mongomodel-2c4db19"这个压缩包中,很可能是MongoModel...

    Rails相关电子书汇总

    2. **ActionController**:负责处理HTTP请求,并将数据转发给相应的模型和视图。它管理着应用的业务逻辑和控制流程。 3. **ActionView**:负责生成HTML或其他类型的响应,通常与模板系统一起工作,将数据以用户友好...

    rails 3.2 API

    6. **ActionPack**:包含ActionController和ActionView,提供了处理HTTP请求和响应的一系列工具。 7. **ActiveSupport**:这是一个工具库,包含了各种实用的类和模块,如时间处理、字符串操作和集合操作等。Rails ...

    中文版rails教程

    在Ruby on Rails中,开发者可以快速构建功能丰富的动态网站,因为它提供了大量的内置功能和库,如数据库连接、ORM(对象关系映射)系统ActiveRecord、模板引擎ActionView以及路由系统ActionController等。...

    Rails进行敏捷Web开发(所有版本的源码rails3.0-4.0)

    1. Rails 3.0: Rails 3是重大升级,引入了ActionController::Metal,这是一个轻量级的控制器,用于提高性能。同时,它引入了多路由引擎支持,如Rack中间件,使得与其他Web服务器的集成更加容易。此外,ActiveRecord...

    好用的rails 2.0 Api 文档

    Action Controller是Rails中处理HTTP请求的部分。它负责接收请求,调用模型来处理业务逻辑,然后将结果传递给视图进行渲染。控制器方法可以设置HTTP响应的状态码,以及返回给客户端的数据。 **5. Views和Helper方法...

    rails2.3.2

    Rails 作为 Ruby 的主要应用框架之一,两者密切相关。 在压缩包的文件名称列表中,只有一个条目 "rails",这可能意味着压缩包内包含了 Rails 框架的核心文件,如 gemspec 文件、库文件、初始化脚本等。开发者可以...

    Ruby-Rails实战之B2C商城开发

    在本项目"Ruby-Rails实战之B2C商城开发"中,我们将深入探索使用Ruby on Rails这一强大的Web开发框架来构建一个完整的B2C(Business-to-Consumer)在线商城。Rails是Ruby语言的一个核心框架,以其MVC(Model-View-...

    Ruby on Rails实例开发

    此外,它还提供了大量的内置功能和库,如ActiveRecord用于ORM(对象关系映射),ActionController处理HTTP请求,以及ActionView生成响应。 SQLite是一个轻量级的嵌入式数据库,常用于Rails开发中的开发和测试环境。...

    Ruby on Rails Guides v2 - Ruby on Rails 4.2.5

    - **配置**:在`config/routes.rb`文件中添加新的路由规则,例如`get 'new_route' =&gt; 'controller#action'`。 - **效果**:这将在应用中增加一个新的URL路径,指向指定控制器的动作。 #### 七、渲染视图 - **方法*...

    ruby on rails api

    2. **ActionController**:处理HTTP请求,并调用模型来执行业务逻辑,然后将结果传递给视图进行渲染。控制器包含了各种助手方法,用于辅助处理请求和响应。 3. **ActionView**:负责生成HTTP响应的视图部分,可以是...

    railsAPI

    ActionController是Rails中的一个关键组件,它处理HTTP请求,调用控制器方法,并返回响应。控制器方法可以操作模型,处理数据,然后选择适当的视图来呈现结果。对于API应用,通常返回JSON或XML格式的数据。 在Rails...

Global site tag (gtag.js) - Google Analytics