Rails Study(11)Action Controller Overviews - Cookies

Rails Study(11)Action Controller Overviews - Cookies

5. Cookies
You application can store small amounts of data on the client ----cookies, that will be persisted across requests and even sessions.

class CommentsController < ApplicationController
def new
@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]
cookies[:commenter_name] = @comment.name
else
cookies-delete(:commenter_name)
end
redirect_to @comment.article
else
render :action => "new"
end
end
end

To delete a cookie value, we need to use cookies.delete(:key)

6 Rendering xml and json data
class UsersController < ApplicationController
def index
@users = User.all
respond_to do |format|
format.html
format.xml { render :xml = > @users }
format.json { render json: @users }
end
end
end

Notice that in the above case code is render :xml => @users and not render :xml => @users.to_xml. That is because if the input is not string then rails automatically invokes to_xml.

7 Filters
Filters are methods that are run before, after or "around" a controller action.

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

A common before filter is one which requires that a user is logged in for an action to be run.

class ApplicationController < ActiveController::Base
before_filter :require_login

private

def require_logn
unless logged_in?
flash[:error] = "You must be logged in to access this section"
redirect_to new_login_url
end
end

def logged_in?
!!current_user
end
end

!! is to convert something into true or false.

If a before filter renders or redirects, the action will not run. If there are additional filters scheduled to run after that filter they are also cancelled.

You can prevent this filter from running before particular actions with skip_before_filter:

class LoginsController < ApplicationController
skip_before_filter :reqire_login, :only => [:new, :create]
end

The :only option is used to only skip this filter for these actions, and there is also an :except option which works the other way.

7.1 After Filters and Around Filters
Obviousl, after filters can not stop the action from running.

7.2 Other Ways to Use Filters
Use a block directly with the *_filter methods. The block receives the controller as an argument, and the require_login filter from above could be rewritten to use a block:

class ApplicationController < ActionController::Base
before_filter do |controller|
redirect_to new_login_url unless controller.send(:logged_in?)
end
end

Note that the filter in this case uses send because the logged_in? method is private and the filter is not run in the scope of the controller.

Use a class to rewrite the login filter.

class ApplicationController < ActionControlller::Base
before_filter LoginFilter
end

class LoginFilter
def self.filter(controller)
unless controller.send(:logged_in?)
controller.flash[:error] = "you must be logged in"
controller.redirect_to controller.new_login_url
end
end
end

method will came after :, but class came after directly the *_filter keywords.

8. 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 i 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 make using XMLHttpRequest(AJAX).

The default action taken when these criteria are not met is to render a 400 Bad Request response.

class LoginsController < ApplicationController
verify :params => [:username, :password],
:render => {:action => "new"},
:add_flash => {
:error => "Username and password required to log in"
}
def create
@user = User.authenticate(params[:username], params[:password])
if @user
flash[:notice] = "you're logged in"
redirect_to root_url
else
render :action => "new"
end
end
end

There is something rather import 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.

class LoginsController < ApplicationController
verify :params => [:username, :password],
:render => {:action => "new"},
:add_flash => {
:error => "username and password required to log in"
},
:only => :create
end

9 Request Forgery Protection
Cross-site request forgery is a type of attack in which a site tricks a user into making requests on another site.

1. make sure all "desructive" actions (create, update and destroy) can only be accessed with non-GET requests.
2. Add a non-guessable token which is only known to your server to each request. If a request comes in without the proper token, it will be denied access.

erb forms as follow:
<%= form_for @user do |f| %>
<%= f.text_field :username %>
<%= f.text_field :password %>
<% end %>

I got this in my form
<input name="authenticity_token" type="hidden" value="CKcVLfMFYxIEwOzEUMg4DK5VAY43Li/LhoQKypela70=" />

This is available through the method form_authenticity_token.

10. The Request and Response Objects
10.1 The request Object
There are some properties of request object.
host ------------------The hostname used for this request
domain(n=2)-------
format ---------------The content type requested by the client
method--------------
get?, post?, put?, delete?,head?
-------------------------Returns true if the HTTP method is GET/POST/PUT/DELETE/HEAD
headers--------------
port-------------------
protocol-------------Returns a string containing the protocol used plus "://", for example "http://"
query_string-------
remote_ip --------- The IP address of the client
url -------------------- The entire URL used for the request.

10.1.1 path_parameters, query_parameters, and request_parameters

10.2 The response Object
Properties of response
body ------------- This is the string of data being sent back to the client.
status ------------ The HTTP status code for the response, like 200 for a successful request or 404 for file not found.
location ---------- The URL the client is being redirected to, if any
content_type--- The content type of the response
charset ----------- The character set being used for the response. Default is "utf-8".
headers ----------

10.2.1 Setting Custom Headers
response.headers["Content-Type"] = "application/pdf"

11 HTTP Authentications
Rails comes with two built-in HTTP authentication mechanisms:
Basic Authentication
Digest Authentication

11.1 HTTP Basic Authentication
In my sample project, I have the experiences

before_filter :authenticate, :except => [:index, :show]
before_filter :authenticate, :only => :destroy

And authenticate in my ApplicationController

private

def authenticate
authenticate_or_request_with_http_basic do |user_name, password|
user_name == 'admin' && password == 'password'
end
end

Certainly, we can try to encode the password Digest::SHA1.hexdigest(password).

11.2 HTTP Digest Authentication
USERS = { "life" => "world" }
authenticate_or_request_with_http_digest do |username|
USERS[username]
end

12 Streaming and File Downloads
Sometimes we want to send a file instead of rendering an HTML page.

send_file is a convennience method that lets you provide the name of a file on the disk.

To stream data to the client, use send_data.

require "prawn"
class ClientsController < ApplicationController
def download_pdf
client = Client.find(params[:id])
send_data generate_pdf(client),
:filename => "#{client.name}.pdf",
:type => "application/pdf"
end

private

def generate_pdf(client)
Prawn::Document.new do
text client.name, :align => :center
text "Address: #{client.address}"
text "Email: #{client.email}}"
end.render
end
end

The download_pdf action above will generate the PDF document and returns it as a string. This string will then be streamed to the client as a file download and a filename will be suggested to the user.

12.1 Sending Files
Use send_file method to send a file that already exists on disk.

class ClientsController < ApplicationController
def download_pdf
client = Client.find(params[:id])
send_file("#{Rails.root}/files/clients/#{client.id}.pdf",
:filename => "#{client.name}.pdf",
:type => "application/pdf")
end
end

12.2 RESTful Downloads
class ClientsController < ApplicationController
def show
@client = Client.find(params[:id])

respond_to do |format|
format.html
format.pdf { render :pdf => generate_pdf(@client) }
end
end
end

In order to make this work, we need to add the PDF MIME type of Rails. This can be done by adding the following line to the file
config/initializers/mime_types.rb:
Mime::Type.register "application/pdf", :pdf

Notices, configuration files are not reloaded on each request, so we need to restart the server.

13 Parameter Filtering
14 Rescue
14.1 The Default 500 and 404 Templates
These HTML files are in the public folder, 404.html and 500.html.

14.2 rescue_from

references:
http://guides.rubyonrails.org/action_controller_overview.html
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值