请求(request)信息 |
获取请求信息 | params[:参数名]
可以获得的信息 |
主机信息 | 《form method="POST"》下定义的表格传送来的信息 | 询问信息 query | url后面 ?键名=值&...下面的信息 | 路径参数 | 路径/books/1这样的1的部分 |
| 数组 |
路径 | key后面加[] 例: /...?sampleArray[]=...&... | 方法参数 | 还是单纯的符号(symbol) params[:sampleArray] |
| 哈希表 |
路径 | key后面加上[哈希值] 例: /...?hashArray[hashVal]=...&... | 方法参数 | 还是单纯的符号(symbol) params[:hashArray] |
| | | | | | | | | | | | | | |
|
指定可以获取的数据 黑白名单 | params.require(model).permit(attr,...)
参数 |
model | 模型名 | attr, ... | 允许获取的属性值的哈希值(符号symbol) | | | | | | |
| 遇到获取不允许值时指定处理 | 默认拒绝 config.action_controller.action_on_unpermitted_parameters | | | | | | |
|
获取头信息 |
头信息 | 附加的一系列和用户操作无关的信息 | 例 | 客户端(浏览器)对应的语言,浏览器种类,链接地址等 | 其他 | 请求时的成为请求头信息 (request header information) | | | | |
request.headers['...']
主要的头信息标签 | 内部名 HTTP_.... 例子: HTTP_ACCEPT_LANGUAGE
Accept | 客户端支持的内容种类 | Accept-Language | 客户端支持的语言(按优先度排) | Authorization | 证书信息 | Host | 请求的主机信息 | Referer | 链接信息 | User-Agent | 客户端种类 | | | | | | | | |
| 还可以获取服务器环境变量 request.headers['...'] |
GATEWAY_INTERFACE | CGI的校对
返回值例: CGI/1.2 | QUERY_STRING | 请求信息 返回值例: id=1 | PATH_INFO | 路径信息 返回值例: /ctrl/req_head2 | REMOTE_ADDR | 客户端的ip地址 返回值例: ::1 | REQUEST_METHOD | HTTP方法 返回值例: GET | REQUEST_URI | 请求是的url 返回值例: /ctrl/red_head2?id=1 | SERVER_NAME | 服务器名 返回值例: localhost | SERVER_PORT | 服务器接口号 返回值例: 3000 | SERVER_PROTOCOL | 服务器用的协议 返回值例: HTTP/1.1 | SERVER_SOFTWARE | 使用的服务器软件 返回值例: puma 3.6.0 Sleepy Sunday Serenity | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | |
|
获取头信息和服务器信息的专用方法 | #TODO: F2634985-5CD9-4CBD-B8E0-C7B7A4184923 p333~334 因为上面的也可以用,暂时省略 |
文件上传 | 传上的文件的接收 form_tag/for ...multipart: true do ... submit_tag ... end
form_tag form_for 选项设置 | 必须 multipart: true | | | | | | | | | | | | | | | | | | |
|
上传的文件方法 | 类型UploadedFile
original_filename | 源文件名 | content_type | 内容的类型 ? | size | 大小
1.megabyte这样来进行比较 | read | 读取文件内容 | File.extname(...).downcase File.extname(...).upcase | 获取文件拓展名 注意:参数应该是文件名 | | | | | | | | | | | File.extname(你的文件.original_filename).downcase |
文件保存 本地系统 | File.open("/Users/xxxx/Desktop/github/Learning-Ruby/File/#{name}", 'wb') do |file| file.write(upload.read) end |
文件保存 数据库 | # TODO: p337~339 |
获取文件后缀 | File.extname(你的文件.original_filename).downcase |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
回应(response)的操作 |
response | 返回处理的结果等 |
概览 |
render | 呼出模板/文本/脚本等,输出通用的结果 | redirect_to | 向指定地址重定向 | send_file | 输出文件 | send_data | 输出二进制文件 | head | 只输出回应的头信息?(応答ヘッダー) | | | | | | | | | | |
|
render(1) | 最常用。 如果没有呼出,则默认呼出这个,执行设定好的模板(get '.../...') 呼出模板的用法
呼出同一个视图控制器的模板(templata) | render action: 't1' | 呼出其他视图控制器的模板(templata) | render template: 'sample/t1' | 呼出应用外部的模板(templata) | render file: '...' 绝对路径 多个应用共有一个模板时候用 | 三个的符号都可以省略 | | 呼出部分模板 传送门 |
位置 | 模板内(layout或者部分模板template) | 文件命名规则 | 开头带_
| 呼出方法 | render url render partial: url
render "sample"
render partial: "sample"
注: ● 全体通用的(/app/views/ application)看做全体的部分模板, 呼出不需要相对路径 ● 路径是 /app/views/后面的相对路径 ● 和主模板在一个文件夹的呼出时可以省略到该文件夹部分 |
| | | 注意: render默认放回200(:ok)状态码,可以通过status: 选项自己指定 |
render(2) | 直接输出 只用在debug 会使layout无效
输出纯文本 无视一切符号的意义 | render plain: '...' | 输出纯文本 有符号的意义 | render html: '...'.html_safe | 用erb输出 | render inline: '...' erb的代码字符串 | 主要 | 这三个都会使layout无效 因为这是debug 如果需要layout,要自己制定 | | | | | | | | | | | | | 注意: render默认放回200(:ok)状态码,可以通过status: 选项自己指定 |
head | 只返回状态码 head status [, opt]
参数 |
status | 状态 数值或者符号 | opt | 应答头(応答ヘッダー) 头: 值的形式 |
| status |
符号 | 状态码 | 含义 | :ok | 200 | 成功 | :created | 201 | 资源生成成功 | :moved_permantly | 301 | 资源永久性移动了 | :found | 302 | 资源暂时移动了 | :see_other | 303 | 资源在其他地方 | :unauthorized | 401 | 要认证 | :forbidden | 403 | 访问被禁止 | :not_found | 404 | 资源不存在 | :method_not_allowed | 405 | HTTP方法不被允许 | :internl_server_error | 500 | サーバーエラー | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | |
|
redirect_to | 返回结果并且重定向 redirect_to url [,status=302]
url | 和url_for一样的参数
controller | 视图控制器名 | action | 动作(方法名)(controller#method) | host | 主机名(覆盖现在的主机) | protocol | 协议名(覆盖现在的协议) | anchor | 锚名? | only_path | 是否返回相对url(是否省略协议/主机/接口) 不指定host的话默认true | trailing_slash | 末尾要不要/ 默认false | user | HTTP识别用的用户名 | password | HTTP识别用的密码 | 只指定一个:back | 链接向之前一个链接 (返回Referer header) |
| status | 数字或者符号
符号 | 状态码 | 含义 | :ok | 200 | 成功 | :created | 201 | 资源生成成功 | :moved_permantly | 301 | 资源永久性移动了 crawler记录 | :found | 302 | 资源暂时移动了 crawler不记录 | :see_other | 303 | 资源在其他地方 | :unauthorized | 401 | 要认证 | :forbidden | 403 | 访问被禁止 | :not_found | 404 | 资源不存在 | :method_not_allowed | 405 | HTTP方法不被允许 | :internl_server_error | 500 | サーバーエラー |
| 添加flash | redirect_to @sample, notice: '...' 两个基本一样的
notice | 用于传出通知 任意值 | alert | 用于穿出警告和错误(error) 任意值 | redirect_to ({controller: :controller_test, action: :t8}), test_flash: 'just a test' | | | | | | | | | | | | | | |
|
redirect_back | 重定向到前一个(Referer头的前一个) redirect_back fallback_location: url fallback_location: url 前一个不存在的时候重定向的目的地
url | 和url_for一样的参数
controller | 视图控制器名 | action | 动作(方法名)(controller#method) | host | 主机名(覆盖现在的主机) | protocol | 协议名(覆盖现在的协议) | anchor | 锚名? | only_path | 是否返回相对url(是否省略协议/主机/接口) 不指定host的话默认true | trailing_slash | 末尾要不要/ 默认false | user | HTTP识别用的用户名 | password | HTTP识别用的密码 | 只指定一个:back | 链接向之前一个链接 (返回Referer header) |
|
|
send_file send_data |
发送文件 | send_file path [,opt] 也就是下载链接 | 发送二进制文件 | send_data path [,opt] 表示图片用 |
参数 |
| opts |
filename | 下载的文件名 默认: 原文件名 | type | 内容的种类 默认: application/octet-stream | disposition | 是inline表示(:inline) 还是直接使用户下载(:attachment) | status | 状态码 默认200(ok) | url_based_filename | 是否根据下载的链接生成文件名 默认: false (filename指定了的话优先filename) | | | | | | |
| | | | | | | | | | | | | | | | |
|
(补充) 输出日志 logger | p350
logger.unknow(msg) | 未知错误 | loggger.fatal(msg) | 致命错误 | logger.error(msg) | 错误 | logger.warn(msg) | 警告 | logger.info(msg) | 信息 | logger.debug(msg) | bug信息 | | | 优先度 | 从上到下递减 | | | | |
|
| |
| |
| |
| |
| |
| |
| |
HTML以外的回应处理 |
概要 | 将处理结果以XML/JSON形式输出 用途: 普通的回应是给人看的,而这种回应是用来把数据输出给其他app |
生成xml/json |
xml | render xml: :sample | json | render json: :sample | 注: 一次可以指定多个不同的model,不用完全一样 |
JBuild生成JSON |
文件后缀 | .json.jbuilder | 构成 | Ruby脚本 | 生成json | json.array!(coll, partial: template, as: var)
参数 |
coll | 对象数组 | partial: template | 描绘每个元素所用的部分模块 注意: 部分模块命名开头_ | as: var | 部分模块里获取每个元素的变量 | | | | |
| | |
例: json.array! @books, partial: 'books/book', as: :book 其他写法: https://www.rubydoc.info/github/rails/jbuilder/Jbuilder:array! | 部分模板内的方法 | 输出键与值 一个 | json.key value
注意: 键和值之间没有空格
参数 |
| 可以嵌套 接闭包 | json.key do json.subkey2 val1 json.subkey2 val2 end | | | | | | | | | | | | | | | | | 例: json.url book_url(book, format: :json) book_url: 由resources自动生成 | 输出键与值 多个 | json.extract! obj, prop, ...
参数 |
obj | 模型对象 | prop | 模型的属性 生成的相当于 | | | | | | | | 备注 | json.pro-name Model.pro-name 也就是说键名和模型的属性名相同 | 省略型 | | | | | | | | | | | | | | | |
例: json.extract! sample, :pro1, :pro2, ... | | | | | | | | | | |
|
Build生成XML | 要在Gemfile最后一句 gem 'activemodel-serializers-xml' 然后运行bundle install
文件后缀 | .xml.builder | 构成 | Ruby脚本 | 生成xml | xml.element([contet] [,attr: value, ...) do ...content... end
参数 |
element | 要素名 | attr | 属性名 | value | 属性值 | content | 代码块的内容 | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | |
|
| |
| |
| |
| |
| |
根据格式要求输出 | respond_to_do |format| format.type { statements } ... end
参数 |
format | 格式控制对象 | type | 回应的格式 | statements | 描绘的代码 | | | | |
| 注 | 也可以带条件 if ... format.type {statements} ... end | 可用的形式 | html, xml, json, rss, atom, yaml, text, js, css, csv, ics | 追加形式 | http/mime_types.rb 格式 Mime::Type.register "text/richtext", :rtf | | | | | | | | | | | | |
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
状态管理 |
Rails可用的状态管理方法 |
cookie | 保存在浏览器的信息 (Rails以外也可用) | session | 保存在cookie, cash, database的做法 (最常用) | flash | 只对现在和下一个HTTP要求有效的特殊session |
|
Cookie |
设置Cookie值 | cookies[:name] = {key: value, ...}
参数 |
name | cookie名 | key | option | value | 选项值 | | | | | | | | | | | | | | |
| option |
value: 必须 | cookie的值 例: sample@wings.msn.to | expires: 必须 | cookie的有效期限 例: 3.hours.from_now 不指定的话,关了浏览器就没了 | domain: | cookie有效的域名 | path: | cookie有效的路径 | secure: | 是否安全化 注: 如果选true, 则只在https下才会 发送cookies | httponly: | 是否只对HTTP有效 防止JavaScript来盗取 | | | | | | | | |
| 永久性cookie | cookies.permanent[:key] = {...} 注意: 有效期为20年, 优先级最高, 设定了expire也无视 | 加密cookies | cookies.encrypted[:key] = {...} yaoyushe/app/config/secrets.yml | 既加密又永久化 | cookies.permanent.encrypted[:key] = {...} | | | | | | | | | | |
|
删除cookie | cookies.delete(:key) 对于设置了domain/path的,需要明确指定domain/path cookies.delete(:key, path: '...') |
读取 | cookies[:key] |
| |
| |
Session |
概要 | 默认情况下使用cookie来保存(CookieStore) 和Cookie基本上一样 不同点: 可以自由改变保存处
CookieStore | 默认保存方法 优点: 快的一笔2333 缺点: 不安全,不保存重要的 单个上限4kb | CacheStore | 保存在服务器cache(应用的cache处) 保存不怎么重要的短期数据 | ActiveRecordStore | 保存在服务器数据库 适合保存核心数据 |
|
设定session值 | session[:key] = value session默认有效期限是关闭浏览器前 保存方法,期限等在/app/config/ |
设定session本身 |
位置 | /app/config/initializer/session_store.rb 如果没有则在该位置自己建一个 | 文件内容 | Rails.application.config.session_store :cookie_store, key: '_XX_session' | 第一个参数 | 数据存储的种类
cookie | :cookie_store 默认值 | 缓存 | :cache_store | 数据库 | :active_record_store Rails4以后和本体分离,需要另外安装 active record-session_store | 使session无效 | :disabled | | |
| 可指定参数 |
key | 存储session使用的键名 默认_session_id(根据项目名来决定) | domain | session键有效的域名 默认nil(现在的域名) | path | session键有效的pass 默认/ | expire_after | session有效期限 nil(关闭浏览器为止) 要永久就设定20.years ● 也可以写成expire_in | secure | 保密通信(HTTPS)下session才有效 默认false | httponly | HTTP cookie是否有效 默认true | | | | | | | | |
| | | | | | | | | | | | |
|
读取 | sample = session[:key] 注: 得到的是以字符串为标签的哈希表 |
删除 | session[:key] = nil |
全部删除 | reset_session |
Flash |
概要 | 只对当前和下一个请求有效 主要用于确认信息等情况,如填完提交了表格提示保存成功等等 |
使用例 | redirect_to @sample, notice: '...' 两个基本一样的
notice | 用于传出通知 任意值 | alert | 用于穿出警告和错误(error) 任意值 |
|
设定值 | flash[:key] = value |
获取值 | flash[:key] |
相关方法 |
flash.now[:key] | 只对当前方法有效的flash | flash.keep(:key) | 指定的key保存到下一个方法 | flash:discard(:key) | 删除指定的key 不指定的话全部删除 | | | | | | | | | | | | | | |
|
| |
| |
| |
| |
| |
筛选(filter) 预处理与后处理 |
前或后执行 | before_action :method [, ...] after_action :method [, ...] 使用的方法用private藏起来 可以用多个方法,直接往后加 用render/redirect_to或者发出异常来中止before_action
选项 | | 只对一部分方法生效 | only: [:t1, :t2, ...] | except | except: [t1, t2, ...] | | | | | | | | | | | | | | |
|
前后执行 | around_action :method [, ...] 使用的方法用private藏起来 注: 用yield来表明action的执行时刻
例 around_action :test
private def test ...before... yield ...after... end |
敲过部分筛选处理 | 母类---子类---孙类
去除继承子母类的 | skip_before_action :action-name skip_around_action :action-name skip_after_action :action-name | 注 | 也可以用only,except | | | | | | | | | | | | | | | | |
|
Rails自带认证的问题 | ①.只能用自带的认证对话框 ②.没办法logout,浏览器关闭前一直是登陆状态 |
用户认证 Rails自带的简单认证 |
authenticate_or_request_with_http_basic(realm) do |name, passwd|
login_procedure
end
返回true/false
参数 |
realm | realm名 默认"Application" | name | 用户名 | passwd | 密码 | login_procedure | 登陆处理 | | |
| | | | |
|
用户认证 Rails自带的更安全认证 |
authenticate_or_request_with_http_digest(realm) do |name|
...
end
返回密码,如果符合就成功,不符合就失败 例:
before_action :auth_
REALM = 'SAMPLE'
USER = { name: 'name', password: '1234'}
def auth_
authenticate_or_request_with_http_digest(REALM) do |n|
USER[:password]
end
|
实现认证密码 |
安装bcrypt库 |
在Gemfile最后添加 | gem 'bcrypt', '~>3.1.7' | 执行: | bundle install | 重启动服务器 | | | | | |
|
使用brcypt库 |
建立用户的模型rails generate model users user_name:string password:string | 在模型里添加 has_secure_password 不要confirmation验证的话 has_secure_password validation:false 注:这个方法(method)自动添加了
password/password_confirmation属性 | 假想属性,不是一定要的 | password属性的必须的认证,字符串长度验证(72以内) | | password/password_confirmation属性的confirmation认证 | 不要的话 | 认证方法 authenticate | |
| 在模型里添加列(string) password_digest 注意: 此列作为密码 登录密码时候用BCrypt::Password.create(@password) | @user = Login.new(:user => @username, :password_digest => BCrypt::Password.create(@password)) | | |
| |
| |
| |
| |
| |
| |
| |
| |
定义共有的动作(application controller) |
位置 | /app/controller/application_controller.rb |
作用 | 所以视图控制器的母类 用于定义 子类需要的帮助类方法(helper method) 大部分视图控制器使用的筛选功能(filter) 应用全体的设定 |
异常处理 | 不应该在每一个具体的视图控制器里,应该在母类里 rescue_from except, with: rescuer
参数 |
except | 异常 | with: rescuer | 处理该异常的方法(method) | | | | | | |
| | | | | | | 注 | 实际产品环境(production)下产生异常会自动呼出异常相对应的页面 位置: /public/ 如404.html |
|
防范 跨站请求伪造(CSRF) Cross-site request fogery | protect_from_fogery with: :...
with: :... | 遇到伪造请求的处理方法
:exception | 生成异常 ActionController: invalidAuthenticityToken | :reset_session | 删除session | :set_session | 换成空的session 默认值 |
| | | | | | | | |
|
按设备分配页面 | 设备信息 request.headers['User-Agent']
request.variant = :mobile | 呼出后缀为 html+mobile.erb 网址...t1?type=mobile | request.variant = :tablet | 呼出后缀为 html+tablet.erb 网址...t1?type=tablet | 没设定request.variant | 呼出后缀为 html.erb 也就是默认 |
|
增加flash变量 | add_flash_type(type, ...) redirect_to里面有两个,notice, alert 增加除此之外的用 add_flash_type(:test1, :test2, ...)
type | 键(符号symbol) | 使用 | redirect_to url, test: 'test' | | | | | | |
|
多个视图控制器/模型共有的逻辑 |
放置位置 | /app/controllers/concerns/ /app/models/concerns |
写法 p399 |
module name
extend ActiveSupport::Concern # 只含有实例方法的话可以省略extend ActiveSupport::Concern
included do
#call_clazz # 呼出包含此模块的类的类方法
end
module ClassMethods
#clazz # 类方法的定义
end
#instance # 实例方法
end
call_clazz | 呼出方法 呼出包含此模块的类的类方法 | module ClasssMethod | 类方法的定义 | instance | 实例方法 | extend ActiveSupport::Concern | 共通的内容 只含有实例方法的话可以省略 include的成为实例方法 extend的成为静态方法 | | | 例子
module Login extend ActiveSupport::Concern included do before_action :login end private def login #render plain: 'login module test successfully' end end |
使用 | include Module-Name |
文件命名规则 | 字母要一直,单词之间_间隔,module名的单词首字母大写 如 test.rb ---> module Test ni_hao.rb ---> module NiHao |
| |
| |
| |
| |
| |