#126 楼 @night_7th 好建议,其实我 demo https://github.com/baya/build-an-api-rails-demo 里已经加了 skip_before_action :verify_authenticity_token
, 我在文章里注明下
#3 楼 @xiaoronglv 我们的工作内容也差不多,客户那边有专职的翻译人员,我们程序员提供翻译的模版和翻译的 key
我刚才试验了下没有问题:
curl -i -X POST -d "user[email][email protected]&user[password]=123123" http://localhost:3000/api/v1/sessions
HTTP/1.1 200 OK
X-Frame-Options: SAMEORIGIN
X-Xss-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Content-Type: application/json; charset=utf-8
X-Ratelimit-Limit: 10000
X-Ratelimit-Remaining: 9999
Etag: W/"c0e0519f9c89a846b241a7b0dccd6369"
Cache-Control: max-age=0, private, must-revalidate
X-Request-Id: 22758305-9c86-496d-9223-a76c5828038a
X-Runtime: 0.547032
Vary: Origin
Server: WEBrick/1.3.1 (Ruby/2.1.2/2014-05-08)
Date: Tue, 22 Dec 2015 05:09:27 GMT
Content-Length: 150
Connection: Keep-Alive
Set-Cookie: request_method=POST; path=/
{"session":{"id":1,"name":"gg-user","admin":false,"token":"izrFiion7xEe2ccTj0v0mOcuNoT3FvpPqI31WLSCEBLvuz4xSr0d9+VI2+xVvAJjECIoju5MaoytEcg6Md773w=="}}%
你可以看下我写的 demo 代码: https://github.com/baya/build-an-api-rails-demo
提供一个折衷的方法,需要在路由中加一个辅助方法:
Rails.application.routes.draw do
def point_to_latest(version = "v1", path)
to = {
"search" => "#{version}/issues#search"
}[path]
return "latest/#{path}", {to: to}
end
namespace :rest do
namespace :api do
namespace :v1 do
get '/search', to: 'issues#search'
end
# 我希望latest自动指向v1版本下的controller处理
# match 'latest/*path', to: redirect{|params, request| "/rest/api/v1/#{params[:path]}?#{request.query_string}"} , via: :get
get *point_to_latest("search")
end
end
end
中国版的 The Rails 4 Way?
我还是习惯性的想为 ruby 辩解几句,sidekiq_worker(重构前的 worker) = sidekiq + 暴走 rails app, go_worker(重构后的 worker) = go_workers + 精简的暴走业务代码,看到区别了没有,一个是拖家带口臃肿不堪,一个是轻装上阵如履平地。按楼主提供的信息:8 核 16G 机器 跑 sidekiq 的任务,我保守猜测一下,一台机器启动了 8 * 2 = 16 个 workers, 每个 worker 消耗 500M 内存 (我现在有一个中等规模的 rails 项目,每个 woker 平均消耗 400 M 内存,以暴走的规模来看应该比我们消耗的内存多些), 总共 8 G 内存,什么任务都没有跑就已经吃掉 8G 内存了,但这不是 ruby 的错,是 rails 的错。其实如果脱离 rails, 单纯用 ruby 来写这些后台业务代码,效果也会不错的。
这么低调的炫耀妹子,其他公司可以学学
module A
class User
def self.transaction(&block)
puts "A::User transaction call #{block.call}"
end
end
end
module B
class User
def self.transaction(&block)
puts "B::User transaction call #{block.call}"
end
end
end
module C
class User
def self.transaction(&block)
puts "C::User transaction call #{block.call}"
end
end
end
module D
class User
def self.transaction(&block)
puts "D::User transaction call #{block.call}"
end
end
end
def tr(*args, &block)
bl = block
args.reverse.each {|arg|
# 这里不能使用 bl = -> { arg.transaction(&bl)}, 否则 lambda 的闭包作用会导致 SystemStackError
bl = create_tr_lambda(arg, &bl)
}
bl.call
end
def create_tr_lambda(arg, &block)
-> {arg.transaction(&block)}
end
tr(A::User, B::User, C::User, D::User) do
puts "begin transaction from D::user"
end
inner_bl = -> {}
d = -> {D::User.transaction(&inner_bl)}
c = -> {C::User.transaction(&d)}
b = -> {B::User.transaction(&c)}
a = -> {A::User.transaction(&b)}
汪汪汪 是几层意思,已经承认是小狗了?
这楼层盖的,我还以为留了动作片的种子
#47 楼 @fleuria 你说了个人体会,这点我是赞同的,关于测试这块的一些评价我也是出于自己的个人经验有感而发的,我其实有一段非常长的写测试的经历,我对写测试的熟练程度可能比这个坛子里大多数人都要多些,并且我现在仍然会对系统的一些比较重要,比较核心的地方写测试。你说的覆盖到好过没覆盖到
, 差的测试好过没有测试
等等这些我认为是写测试的忌讳,写测试是一件很耗费精力的事情,这个精力既包括脑力,也包括体力,程序员的精力既是有限的,也是宝贵的,把程序员的这些宝贵精力消耗在差的测试上,或者是一些并不是很重要的代码的覆盖上岂不是一种严重浪费,当然如果你觉得自己精力好,或者觉得项目的每一个地方都很重要,都不能有任何闪失,你可以继续这样做。以我的个人经验做个小结:如果决定写测试,那务必就写出质量好的,能够用在刀刃上的测试代码,如果做不到,还不如前期认认真真思考,做好全面的设计,忘记重构,忘记以后再去改善代码质量等等之类将来的事情,并且索性大方点把测试的任务交给 QA 团队去做。
#38 楼 @yue 你说的不错,写测试代码确实是一件好事,甚至可以说是一件政治正确的事情,但是好人也经常干坏事,写测试代码就如同一个经常干坏事的好人,虽然它的本意是想做些好事情,但是很多不好事情的事情确实是发生在测试代码中,我补充一些我的观点,下面这些场景以我为主角,
片面追求测试覆盖率,导致写了很多类似于 assert 1==1 之类的测试代码;
大量的使用 mock, stub 之类的东西 (很多时候为了解耦测试代码,又不得不用这些东西),虽然测试通过了,但是上线后,系统被残酷的线上环境虐成渣渣;
自认为自己写的测试代码很清晰,可以当作文档,然后就真的不写文档了,但是过一段时间后,发现读测试代码比读源码还难;
写了些测试代码后,盲目地自信,整天惦记着重构的事,当真的要重构时,却发现项目代码和测试代码要一块重构,每天改测试代码改的要死;
写了些测试代码后,盲目地自信,认为打造一个 自动化 (automatic), 反复进行 (regression tests) 的测试系统很简单,并且幻想这个自动化测试系统会很可靠,于是每次通过 CI 成功提交代码后,都会自欺欺人地说:妥妥的。然后第二天被老板骂的找不到北。 打造一个可靠的自动化测试系统,需要一个研发团队持续不断的努力,需要大量的工具,流程和文档,而不只是一些测试代码。
#35 楼 @emanon TDD 滥用,就像一个有点犯二的强迫症患者,每次出门都特意去检查房间的灯是否关了,当然家里没有人,灯是需要关闭的,但是这种检查应该是下意识的动作,不应该耗费大量的精力去特意检查,我们需要培养的是随手关灯的习惯,而不是这种变态的检查,退一步讲,即使哪天回到家,发现灯没有关,这也不是一件大不了的事情,无非是浪费了些电,减少了些灯泡的寿命。
编写代码很多时候讲究的是一气呵成,TDD 那种写点代码,测试一下,写点代码,测试一下的节奏实在是像一群讨厌的苍蝇在你的耳朵边不停地嗡来嗡去,很痛苦的。
我曾经参与过一个 rails 项目的开发,此项目的测试覆盖率达到了惊人的 99.99999%, 测试代码的规模和复杂程度已经远远超过项目本身了,有时候花了 10 分钟改个代码,却需要花一个小时甚至更长的时间写测试,更气人的是你还必须写测试。让人啼笑皆非的是有次我发现项目中有段代码没有用处,然后把它删除了,然后测试时一片红,后来我跟同事确认这段代码在项目中确实没有什么用,但是测试需要它,更恐怖的是这些测试代码是耦合的,所以为了测试通过,这段代码一直保留着。
现在很多用 rails 的公司要求程序员 TDD,这实在是一个不明智的要求。