| 请求(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) | | 文件命名规则 | 开头带_ /../_sample.html.erb | | 呼出方法 | 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_procedureend 返回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 nameextend ActiveSupport::Concern # 只含有实例方法的话可以省略extend ActiveSupport::Concern
included do#call_clazz # 呼出包含此模块的类的类方法
endmodule 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 |
| | |
| | |
| | |
| | |
| | |