guides.rubyonrails.org 读书笔记(三)

Action Controller Overview

For most conventional RESTful applications, the controller will receive the request (this is invisible to you as the developer), fetch or save data from a model and use a view to create HTML output.

 

1. Methods and Actions

 

A controller is a Ruby class which inherits from ApplicationController and has methods just like any other class. controller初始化过程:When your application receives a request, the routing will determine which controller and action to run, then Rails creates an instance of that controller and runs the method with the same name as the action.

 

Note that the empty method from the example above could work just fine because Rails will by default render the new.html.erb view unless the action says otherwise.

Only public methods are callable as actions. It is a best practice to lower the visibility of methods which are not intended to be actions, like auxiliary methods or filters.

 

2. Parameters

You will probably want to access data sent in by the user or other parameters in your controller actions. There are two kinds of parameters possible in a web application. The first are parameters that are sent as part of the URL , called query string parameters. The query string is everything after “?” in the URL . The second type of parameter is usually referred to as POST data. This information usually comes from an HTML form which has been filled in by the user. It’s called POST data because it can only be sent as part of an HTTP POST request. Rails does not make any distinction between query string parameters and POST parameters, and both are available in the params hash in your controller.

 

2.1 Hash and Array Parameters

The params hash is not limited to one-dimensional keys and values. It can contain arrays and (nested) hashes.

There are two types:

(1).  GET /clients?ids[]=1&ids[]=2&ids[]=3

(2).

< form action = "/clients" method = "post" >
   < input type = "text" name = "client[name]" value = "Acme" />
   < input type = "text" name = "client[phone]" value = "12345" />
   < input type = "text" name = "client[address][postcode]" value = "12345" />
   < input type = "text" name = "client[address][city]" value = "Carrot City" />
</ form >

Note that parameter values are always strings; Rails makes no attempt to guess or cast the type.

Note that the params hash is actually an instance of HashWithIndifferentAccess from Active Support, which acts like a hash that lets you use symbols and strings interchangeably as keys.

 

2.2 Routing Parameters

 

The params hash will always contain the :controller and :action keys, but you should use the methods controller_name and action_name instead to access these values.

 

2.3 default_url_options

进一步分析实际作用

 

3.  Session

Your application has a session for each user in which you can store small amounts of data that will be persisted between requests. The session is only available in the controller and the view and can use one of a number of different storage mechanisms:

  • CookieStore – Stores everything on the client.
  • DRbStore – Stores the data on a DRb server.
  • MemCacheStore – Stores the data in a memcache.
  • ActiveRecordStore – Stores the data in a database using Active Record.

3.1 Accessing the Session

 

 

3.2  The Flash

 

The flash is a special part of the session which is cleared with each request. This means that values stored there will only be available in the next request, which is useful for storing error messages etc.

 

3.2.1 using flash normally

flash[ :notice ] = "You have successfully logged out"

Note it is also possible to assign a flash message as part of the redirection.

redirect_to root_url, :notice => "You have successfully logged out"

 

If you want a flash value to be carried over to another request, use the keep method:

flash.keep

 

3.2.2 flash now

By default, adding values to the flash will make them available to the next request, but sometimes you may want to access those values in the same request . For example, if the create action fails to save a resource and you render the new template directly, that’s not going to result in a new request, but you may still want to display a message using the flash. 注意了,render是不产生new or next request的,所以需要:

flash.now[ :error ] = "Could not save client"

       render :action => "new"

 

4. Cookies

 

Your application can store small amounts of data on the client — called cookies — that will be persisted across requests and even sessions.

class CommentsController < ApplicationController
  def new
    # Auto-fill the commenter's name if it has been stored in a cookie
    @comment = Comment.new(:name => cookies[:commenter_name])
  end
 
  def create
    @comment = Comment.new(params[:comment])
    if @comment.save
      flash[:notice] = "Thanks for your comment!"
      if params[:remember_name]
        # Remember the commenter's name.
        cookies[:commenter_name] = @comment.name
      else
        # Delete cookie for the commenter's name cookie, if any.
        cookies.delete(:commenter_name)
      end
      redirect_to @comment.article
    else
      render :action => "new"
    end
  end
end

 

Note that while for session values you set the key to nil , to delete a cookie value you should use cookies.delete(:key) .

 

5.  Rendering xml and json data

 

6.  Filters

 

Filters are methods that are run before, after or “around” a controller action. 常见于阻止action 运行,终止action运行等

Filters are inherited, so if you set a filter on ApplicationController , it will be run on every controller in your application.

(1) "Before filters" may halt the request cycle.

before_filter :require_login

skip_before_filter :require_login , :only => [ :new , :create ]

(2) After Filters and Around Filters

 

6.2 Other Ways to Use Filters

 

7. Verification

 

Verifications make sure certain criteria are met in order for a controller or action to run. They can specify that a certain key (or several keys in the form of an array) is present in the params , session or flash hashes or that a certain HTTP method was used or that the request was made using XMLHttpRequest (Ajax).

 

The default action taken when these criteria are not met is to render a 400 Bad Request response, but you can customize this by specifying a redirect URL or rendering something else and you can also add flash messages and HTTP headers to the response.

 

8. Request Forgery Protection

class LoginsController < ApplicationController

  verify :params => [:username, :password],
         :render => {:action => "new"},
         :add_flash => {
           :error => "Username and password required to log in"
         }

 

Now the create action won’t run unless the “username” and “password” parameters are present, and if they’re not, an error message will be added to the flash and the new action will be rendered. But there’s something rather important missing from the verification above: It will be used for every action in LoginsController, which is not what we want. You can limit which actions it will be used for with the :only and :except options just like a filter:

 

 

9. Request Forgery Protection

The first step to avoid this is to make sure all “destructive” actions (create, update and destroy) can only be accessed with non-GET requests. If you’re following RESTful conventions you’re already doing this.

 

The form_authenticity_token generates a valid authentication token. That’s useful in places where Rails does not add it automatically, like in custom Ajax calls.

 

 

10. The Request and Response Objects

 

In every controller there are two accessor methods pointing to the request and the response objects associated with the request cycle that is currently in execution. The request method contains an instance of AbstractRequest and the response method returns a response object representing what is going to be sent back to the client.

 

 

10.1

Rails collects all of the parameters sent along with the request in the params hash, whether they are sent as part of the query string or the post body. The request object has three accessors that give you access to these parameters depending on where they came from.

 

 

10.2 The response Object

The response object is not usually used directly, but is built up during the execution of the action and rendering of the data that is being sent back to the user, but sometimes – like in an after filter – it can be useful to access the response directly.

 

 

11. HTTP Authentications

 

Rails comes with two built-in HTTP authentication mechanisms:

  • Basic Authentication
  • Digest Authentication

11.1  Basic Authentication

 

Using the built-in authentication is quite easy and only requires you to use one method, authenticate_or_request_with_http_basic .

???Digest:: SHA1 .hexdigest(password) == PASSWORD

 

一个设计思路:

With this in place, you can create namespaced controllers that inherit from AdminController . The before filter will thus be run for all actions in those controllers, protecting them with HTTP basic authentication.

 

 

11.2  Digest Authentication

具体使用场合和使用方法,需要了解

 

 

12. Streaming and File Downloads

Sometimes you may want to send a file to the user instead of rendering an HTML page. All controllers in Rails have the send_data and the send_file methods, which will both stream data to the client.

 

12.1  Send.data

 

12.2  Sending Files

 

12.3  RESTful Downloads

Rails provides an easy and quite sleek way of doing “RESTful downloads”.

 

 

设计要点:

It is not recommended that you stream static files through Rails if you can instead keep them in a public folder on your web server. It is much more efficient to let the user download the file directly using Apache or another web server, keeping the request from unnecessarily going through the whole Rails stack. Although if you do need the request to go through Rails for some reason, you can set the :x_sendfile option to true, and Rails will let the web server handle sending the file to the user, freeing up the Rails process to do other things. Note that your web server needs to support the X-Sendfile header for this to work.

 

13. Parameter Filtering

The filter_parameter_logging method can be used to filter out sensitive information from the log. It works by replacing certain values in the params hash with “[FILTERED ]” as they are written to the log.

 

14. Rescue

 

Rails’ default exception handling displays a “500 Server Error” message for all exceptions. If the request was made locally, a nice traceback and some added information gets displayed so you can figure out what went wrong and deal with it. If the request was remote Rails will just display a simple “500 Server Error” message to the user, or a “404 Not Found” if there was a routing error or a record could not be found. Sometimes you might want to customize how these errors are caught and how they’re displayed to the user. There are several levels of exception handling available in a Rails application:

 

14.1 The Default 500 and 404 Templates

 

14.2 rescue_from

 

When an exception occurs which is caught by a rescue_from directive , the exception object is passed to the handler. The handler can be a method or a Proc object passed to the :with option. You can also use a block directly instead of an explicit Proc object.

 

 

class ApplicationController < ActionController::Base
  rescue_from User::NotAuthorized, :with => :user_not_authorized
 
  private
 
  def user_not_authorized
    flash[:error] = "You don't have access to this section."
    redirect_to :back
  end
end
 
class ClientsController < ApplicationController
  # Check that the user has the right authorization to access clients.
  before_filter :check_authorization
 
  # Note how the actions don't have to worry about all the auth stuff.
  def edit
    @client = Client.find(params[:id])
  end
 
  private
 
  # If the user is not authorized, just throw the exception.
  def check_authorization
    raise User::NotAuthorized unless current_user.admin?
  end
end

 

工作流程:

 

(1)rescue_from自动直接地捕获exception,When an exception occurs which is caught by a rescue_from directive

上例是User::NotAuthorized; 被父类 的rescue_from捕获;

(2)the exception object is passed to the handle

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值