一、 RVM 自动切换版本
项目目录,建立一个 .rvmrc 文件。
在这个文件里可以很简单的加一个命令:
rvm use 1.9.2
进入到这个目录就会自动切换版本
二、 rails2 发现的注入漏洞
Question.find(:first, :conditions => { :id => { "questions.id" => 1 }}) 生成的 SQL 语句是 SELECT * FROM `questions` WHERE (`questions`.`id` = 1) LIMIT 1 这样已经忽略了真正的 id 参数!完全可以由得到此表的任何数据。解决方法:转换传入参数的类型,数字参数要 to_i 字符串参数要 to_s 这样可以过滤掉客户端传入的哈希。
三、 rails3.0 发现的注入漏洞
Post.where(:id => { :posts => {:author_id => 10} }).first 生成的 SQL 语句是 SELECT * FROM ‘posts’ WHERE (‘ posts.author_id ’ = 10 ) LIMIT 1 已经忽略了 id 参数。解决方法:转换传入参数的类型,数字参数要 to_i 字符串参数要 to_s 这样可以过滤掉客户端传入的哈希。
四、 解决大量数据循环操作问题
假设你有个百万级别客户的电商网站,假设每个用户对象需要 500 字节,上面的代码会在运行的时候消耗 500M 内存,更好的方式是使用 Member.all.find_each 方法代替 Member.all.each ,一次性加载 1000 条 ( 默认 ) 记录到内存中处理,直到将所有数据都处理完, find_each 有两个参数:
batch_size: 一次加载的数据,默认是 1000
start: 统一个处理队列中,开启多个 workers?
五、 常用插件
a) 用户插件 http://github.com/plataformatec/devise
b) 权限插件 https://github.com/ryanb/cancan
用户插件与权限插件整合的例子
https://github.com/RailsApps/rails3-bootstrap-devise-cancan
六、一个避免出现危险的书写习惯
这种写法忽略掉了用户id的判断,应该避免这种书写习惯
ship_add = OrderAddress.find_by_id(id)
ship_add.destroy
应该改成这种书写习惯
ship_add = member_curr.order_address.find_by_id(id)
ship_add.destroy
七、一个没理解的问题
为什么1-0.99得到的结果不是0.01 ?
1-0.99
=> 0.010000000000000009
八、ruby的try方法
尝试执行某些代码,可以避免产生意外错误!看好了!这不是java的异常处理方法!
通常我们要获取某个对象的属性 为了保证安全性一定要先判断对象本身是否为空
@person && @person.name #或者 @person ? @person.name : nil #新的写法 @person.try(:name) #还接受参数和代码块 Person.try(:find, 1) @people.try(:collect) {|p| p.name} @person.try { |p| "#{p.first_name} #{p.last_name}" }
九、查询某条数据的前后N条数据
def self.get_side_logs(id, limit = 5) sql = <<-EOF (SELECT * FROM sign_in_logs WHERE id < #{id} ORDER BY id DESC LIMIT #{limit}) UNION ALL (SELECT * FROM sign_in_logs WHERE id > #{id} ORDER BY id LIMIT #{limit}) ORDER BY ID ; EOF find_by_sql(sql) end
十、字符串的单数复数转换
"Business".singularize => "Busines" # 转单数 "moose".pluralize => "mooses" # 转复数
十一、Gemfile文件
#source定义bundler的资源,默认使用的是 在国内某些地区访问外国很慢可以改成淘宝源 source 'https://rubygems.org' source 'http://ruby.taobao.org' # 第二个参数可以指定版本 gem "rails", "3.0.4" # 也可以不指定版本,这样会安装最新版本 gem 'mysql2' # 如果 require 的包名不同,可以加上 :require明确指定包名 gem "sqlite3-ruby", :require => "sqlite3" # 可以用 Git 做来源,甚至可以指定 branch, tag 或 ref。 gem 'authlogic', :git => 'git://github.com/odorcicd/authlogic.git', :branch => 'rails3' # 也可以直接指定路径 # gem "rails", :path => '/users/local/github/rails' # Group 功能可以根据不同环境载入 group :development, :test do gem "rspec", "~> 2.0" gem "rspec-rails", "~> 2.0" end #版本号的指定方式除了特定版本,还可以指定大于等于某个版本 gem "rails", ">= 2.3.5" #最建议的方式是使用~>语法,意思是x.y固定,但可以大于等于z。 例如~>1.3.5 意思是1.3.5,1.3.6, 1.3.9可以安装,但是1.4.0, 2.0.1不可以安装。 #x版本号升级表示有API发生不可向后的兼容性变动,y版本号升级表示有新功能增加,z版本号升级表示bug修正。因此这种写法可以让我们更有弹性的升级。 gem "rspec", "~> 2.0"
十二、instance_of?和kind_of?方法的区别
module M; end class A include M end class B < A; end class C < B; end b = B.new b.instance_of? A #=> false b.instance_of? B #=> true b.instance_of? C #=> false b.instance_of? M #=> false b.kind_of? A #=> true b.kind_of? B #=> true b.kind_of? C #=> false b.kind_of? M #=> true
十三、方法中判断调用时是否传递了yield
if block_given? tree.each do |board, level| yield board, level end end