rails 指南总结(十一)——controller之Action Controller 概览

1.controller 是什么?

  • Action Controller 是 MVC 中的 C(控制器)。
  • 路由器决定使用哪个控制器处理请求后,控制器负责解析请求,生成相应的输出。
  • 所有的controller都继承自actionController::base

2. 控制器命名约定

  • Rails 控制器的命名约定是,最后一个单词使用复数形式,如: SiteAdminsController,而不是 SiteAdminController 或 SitesAdminsController。但也有例外,如:ApplicationController
  • 遵守这一约定便可享用默认的路由生成器(例如 resources 等),无需再指定 :path 或 :controller 选项,而且 URL 和路径的辅助方法也能保持一致性。
  • 控制器的命名约定与模型不同,模型的名字习惯使用单数形式。

3.参数

在rails中,get与post请求参数均是通过params获取。

3.1 数组:

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

此时,params[:ids] 的值是 [“1”, “2”, “3”]

3.2 散列

在方括号内指定键名,可借助form_for

 <input type="text" name="client[name]" value="Acme" />
 <input type="text" name="client[phone]" value="12345" />

params[:client] 的值是 { “name” => “Acme”, “phone” => “12345”}

3.3 JSON

{ "company": { "name": "acme", "address": "123 Carrot Street" } }

3.4 路由参数

get '/clients/:status' => 'clients#index', foo: 'bar'

params 散列始终有 :controller 和 :action 两个键,params[:foo] 的值会被设为 “bar”,params[:action],其值为 “index”,以及 params[:controller],其值为 “clients”

3.5 健壮参数

Action Controller 的参数禁止在 Avtive Model 中批量赋值,除非参数在白名单中。以防不小心允许用户更新模型中敏感的属性。

params.permit(:id)

若 params 中有 :id 键,且 :id 是标量值,就可以通过白名单检查;否则 :id 会被过滤掉。因此,不能传入数组、散列或其他对象。
若想允许传入整个参数散列,可以使用 permit! 方法:

params.require(:log_entry).permit!

4.会话

应用中的每个用户都有一个会话(session),用于存储少量数据,在多次请求中永久存储。会话只能在控制器和视图中使用,可以通过以下几种存储机制实现:

  • ActionDispatch::Session::CookieStore:所有数据都存储在客户端cookie中(默认也是推荐使用的存储方式)
  • ActionDispatch::Session::CacheStore:数据存储在 Rails 缓存里,会话中不存储重要的数据,或者不需要持久存储(例如存储闪现消息)
  • ActionDispatch::Session::ActiveRecordStore:使用 Active Record 把数据存储在数据库中(需要使用 activerecord-session_store gem)
  • ActionDispatch::Session::MemCacheStore:数据存储在 Memcached集群中(这是以前的实现方式,现在应该改用 CacheStore)

签署会话数据时,还可以传入 :domain 键,指定可使用此 cookie 的域名:

Rails.application.config.session_store :cookie_store, key: '_your_app_session', domain: ".example.com"

4.1 访问会话 session

  1. 会话中的数据以键值对的形式存储
    session[:current_user_id]
  2. 删除会话中数据,把键的值设为 nil
    session[:current_user_id] = nil

4.2 闪现消息flash

  • 闪现消息是会话的一个特殊部分,其中存储的数据只能在下次请求时使用,因此可用于传递错误消息等
    flash[:notice] = "You have successfully logged out."
  • 重定向也可以设置闪现消息。可以指定 :notice、:alert 或者常规的 :flash:
redirect_to root_url, notice: "You have successfully logged out."
redirect_to root_url, alert: "You're stuck here!"
redirect_to root_url, flash: { referral_code: 1234 }
  • flash.keep
    闪现消息保留到其他请求
  • flash.now
    默认情况下,闪现消息中的内容只在下一次请求中可用,但有时希望在同一个请求中使用,针对这种情况,可以使用 flash.now

5.cookies

  • 应用可以在客户端存储少量数据(称为 cookie,通过cookies访问
  • 删除会话中的数据是把键的值设为 nil,但若想删除 cookie 中的值,要使用 cookies.delete(:key) 方法。
cookies.delete(:current_user_id)

6.渲染 XML 和 JSON 数据

def index
    @users = User.all
    respond_to do |format|
      format.html # index.html.erb
      format.xml  { render xml: @users}
      format.json { render json: @users}
    end
  end

我们使用的是 render xml: @users 而不是 render xml: @users.to_xml。如果不是字符串对象,Rails 会自动调用 to_xml 方法。

7. 过滤器

  • 过滤器(filter)是一种方法,在控制器动作运行之前、之后,或者前后运行。
  • 过滤器会继承,如果在 ApplicationController 中定义了过滤器,那么应用的每个控制器都可使用。
  before_action :require_login

如果想跳过某个动作,可以使用 skip_before_action:

  skip_before_action :require_login, only: [:new, :create]

:only 选项的意思是只跳过这些动作。此外,还有个 :except 选项,用法类似。定义过滤器时也可使用这些选项,指定只在选中的动作上运行。

8.HTTP 身份验证

  • HTTP 基本身份验证 http_basic_authenticate_with
 http_basic_authenticate_with name: "humbaba", password: "5baa61e4"

添加 http_basic_authenticate_with 方法后,可以创建具有命名空间的控制器,继承自 AdminsController,http_basic_authenticate_with 方法会在这些控制器的所有动作运行之前执行,启用 HTTP 基本身份验证。(???创建控制器)

  • HTTP 摘要身份验证 authenticate_or_request_with_http_digest
 authenticate_or_request_with_http_digest do |username| USERS[username]

authenticate_or_request_with_http_digest 方法的块只接受一个参数,用户名,返回值是密码。如果 authenticate_or_request_with_http_digest 返回 false 或 nil,表明身份验证失败。

9.数据流和文件下载

数据流和文件下载

10.日志过滤

  • 参数过滤
    可以在应用的配置文件(initializers/filter_parameter_logging.rb)中设置 config.filter_parameters 选项。过滤掉的参数在日志中显示为 [FILTERED]。
config.filter_parameters << :password

注:password不需要手动加,构建项目时自动就会生成。

  • 重定向过滤
    有时需要从日志文件中过滤掉一些重定向的敏感数据,此时可以设置 config.filter_redirect 选项:
config.filter_redirect << 's3.amazonaws.com'

11.异常处理

捕获错误后如果想做更详尽的处理,可以使用 rescue_from。rescue_from 可以处理整个控制器及其子类中的某种(或多种)异常。


class ApplicationController < ActionController::Base
  rescue_from ActiveRecord::RecordNotFound, with: :record_not_found
   rescue_from User::NotAuthorized, with: :user_not_authorized

  private
 
    def record_not_found
      render plain: "404 Not Found", status: 404
    end
# 如果用户没有授权,抛出异常
    def check_authorization
      raise User::NotAuthorized unless current_user.admin?
    end
end

12.强制使用 HTTPS 协议

基于安全考虑,可能希望某个控制器只能通过 HTTPS 协议访问。为了达到这一目的,可以在控制器中使用 force_ssl 方法:


class DinnerController
  force_ssl only: :cheeseburger
  # 或者
  force_ssl except: :cheeseburger
end
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值