Rails 代码组织
concerns目录
-
controller/concerns
;models/concerns
- 放置一些跨
controller/model
共享逻辑, 或者独立模块
- 放置一些跨
lib目录
- 放置通用业务或者非业务相关的代码
Fat Model
-
fat Model 文章
- 让
controller
轻量化 - 把业务逻辑放在
model
中
- 让
Rails Environment
- Rails 加载和启动
- Rails 初始化过程
-
rails 命令
-> 在 bin/ 目录下 - 两种启动方式:
rails s & rake
- Environments & Rails 应用
config/environments
- 配置 Rails 应用
Active Support
-
Active Support 是 Ruby on Rails 的一个组件,扩展了 Ruby 语言,提供了一些实用功能
# irb "".empty? # true " ".empty? # false require 'active_support/all' " ".blank? # true
-
rails
默认加载activesupport gem
-
Active Support 引用
- 按需加载
require 'active_support' require 'active_support/core_ext/object/blank'
- Active Support 提供的所有功能
require 'active_support/all'
-
Active Support 基础扩展
在 rails 中,下面这些值表示空值
blank?
nil & false
- 只有空白的字符串
(判断字符串是否为空使用的是能理解 Unicode 字符的 [:space:],所以 U+2029(分段符)会被视为空白。)
- 空数组和空散列
- 其他能响应
empty?
方法,而且返回值为 true 的对象;
''.blank? # true ' '.blank? # true nil.blank? # true false.blank? # true [].blank? # true {}.blank? # true
present? 方法等价于 !blank?
''.present? # false ' '.blank? # false nil.blank? # false false.blank? # false [].blank? # false {}.blank? # false
deep_dup
方法深拷贝指定的对象,dup
浅拷贝array = ['foo'] duplicate = array.deep_dup duplicate.first.gsub!('str', 'foo') array # => ['string'] duplicate # => ['foo']
try
只想当对象不为 nil 时在其上调用方法,最简单的方式是使用条件语句, try 方法和 Object#send 方法类似,但如果在 nil 上调用,返回值为 nil# 不使用 try unless @number.nil? @number.next end # 使用 try @number.try(:next) nil.try(:size) # nil "hello".try(:length) # 5
to_query
{c: 3, b: 2, a: 1}.to_query # => "a=1&b=2&c=3"
to_json
{a: 1, b: 2}.to_json # "{\"a\":1,\"b\":2}"
-
其他 support
# in? 方法测试某个对象是否在另一个对象中
1.in?([1,2]) # => true
'lo'.in? 'hello' # => true
[1,2].include? 1
# truncate 方法在指定长度处截断接收者, 截断长度包含省略字符串
"Oh dear!".truncate(5) # Oh...
"Oh dear!".truncate(5, omission: '@@@') # "Oh@@@"
# starts_with? 和 ends_with? 是否某个开头或者某个结尾
"foo".starts_with?("f") # => true
"foo".ends_with?("o") # => true
# pluralize 方法返回接收者的复数形式:使其成为复数
"table".pluralize # => "tables"
"ruby".pluralize # => "rubies"
"equipment".pluralize # => "equipment"
# singularize 和 pluralize 相反,
# camelize 方法把接收者变成驼峰式
"admin_user".camelize # => "AdminUser"
# titleize 方法把接收者中的单词首字母变成大写
"fermat's enigma".titleize # => "Fermat's Enigma"
Action Mailer
- 什么是 action mailer
- 用来发送 email
-
SMTP
协议 - 像使用
controller/view
一样来发送邮件
- 配置
- SMTP 原理
(simple mailer transfer protocol)
- 在项目中设置
SMTP
的账户信息
- SMTP 原理
# config/environments/$RAILS_ENV.rb
# smtp 请求
config.action_mailer.delivery_method = :smtp
config.action_mailer.raise_delivery_errors = true
config.action_mailer.perform_caching = false
config.action_mailer.smtp_settings = {
address: ENV['smtp_domain'],
port: ENV['smtp_port'],
domain: ENV['smtp_domain'],
user_name: ENV['smtp_username'],
password: ENV['smtp_password'],
authentication: ENV['smtp_authentication'],
enable_starttls_auto: ENV['smtp_enable_starttls_auto']
}
# .env
export smtp_domain='smtp.qq.com'
export smtp_port='587'
export smtp_authentication='plain'
export smtp_enable_starttls_auto=true
export mailer_sender=''
-
Email 类型
- 遵循view 的命名规则, 根据后缀来决定是 Text类型 还是 HTML类型的邮件
-
*.html.erb
*.text.erb
-
发送Emial
UserMailer.welcome_email(@user).deliver_later
-
操作代码
bin/rails generate mailer UserMailer
app/mailers/application_mailer.rb
class ApplicationMailer < ActionMailer::Base default from: 'from@example.com' layout 'mailer' end
-
app/mailers/user_mailer.rb
-> 用户注册时填写的电子邮件地址发送一封邮件
class UserMailer < ApplicationMailer def welcome_email(user) @user = user @url = 'http://example.com/login' mail(to: @user.email, subject: 'Welcome to My Awesome Site') end end
-
view/user_mailer/welcome_email.html.erb
名字和上面保持一致, 写入邮件想写的东西 - 这一步对应2中的配置
- 最后一步 发送邮件, 对应4 的操作
异步任务
-
资源或时间占用比较多的任务
- 邮件发送
- 批量数据处理
- 数据导出
- 定时任务
- etc.
-
方案设计
- Process 进程
- Thread 线程 (不建议)
-
解决方案
SideKiq
Resque
Delayed Job
Background Job
- etc.
-
Active Job
active_job gem
- 实现统一的异步任务接口
- 需要结合第三方异步任务组件
Rails 安全
-
Session & Cookie
- 不要存一些敏感的东西在其中
- User Input
-
CSRF - RESTful/csrf_token
跨站伪造攻击 -
XSS - h / sanitize
xss 攻击, 白名单过滤 File download/upload
-
System command
禁止用户使用命令 -
HTTP Request methods
严格按照 RESTful 风格 Redirection
-
- 数据库安全
- 批量赋值assignment
params.require
-
SQL injection
sql 注入攻击 -
Unscoped finds
判断是否是当前用户的数据
- 批量赋值assignment
- Configuration(重要信息隐藏)
- running environments
- Passwords
-
filter log parameters
过滤log 敏感信息 Routes
网友评论