分享 你不需要这些 Gems

Rei · 2013年11月22日 · 最后由 franklinyu 回复于 2017年07月15日 · 11046 次阅读

每个开发者都应该有自己的判断和品味,所以我通常只分享我用什么,以及某个技术有什么好处。我不喜欢评价别人用什么,搞技术就是要多折腾,有时不折腾不会了解自己需要什么。

Ruby Web 开发有很多 Gems 可以用,这本来是增加生产力的工具,不过最近经常见到有人遇到的问题来自于他们用了某个不必要的东西,这本来是可以避免的。我把它们整理如下,判断留给开发者自己。

  • Devise
  • Cancan
  • Simple Form
  • Rspec
  • Cells

http://chloerei.com/2013/11/22/you-do-not-need-these-gems/

还有...

  • rails
  • padrino
  • mongoid

Devise Simple Form Cells 确实很多时候都用不到。不过要知道。

这里 unittest 和 rspec,提到的 DSL 的区别在于,rspec 更符合老外的思维和语系。其实对于非 native 的我们来说,用 rspec 并没有占多少优势。

Simple Form 也是我最讨厌的一个 gem。

#3 楼 @xds2000 可能原来的 test:unit 就够了,但是列为不需要,我觉得倒没太有必要。

我提名 oj

simple_form 里面有大量辅助提示的功能,对于做很多表单的场景非常使用,可以 UI,提示,结构可以统一管理,其实是好用的

如果用 form_for 这些工作要不断的重复,而且可以写出好几种风格

安全和认证相关的,自己实在没把后握写出不漏洞百出的逻辑。

我的 php 代码中整个用户和权限系统(RBAC)都是我自己写的,当时在 rails 里面想找对应的 gems,发现 Devise + cancan,但相对于我原来的系统,实在是太难用了,换句话说,对于我这种初级用户来说,真是太难看懂了,出错只能干瞪眼。

#9 楼 @Peter 啊,忘了写 cancan。

#10 楼 @Rei 呵呵,加上吧

simple_form 和 bootstrap 新版有点时间差,各种 dsl,最后不用了 mongo 在 rails 也是官方的 mongo driver,没加 orm

如果只是要做密码加密,用户登录时候验证一下Devise的确是很庞大,但是还有一些场景,比如密码找回,邮箱验证,登录失败锁定,这些有时候也是十分必要的,这时候Devise还是能节省不少时间的。

#7 楼 @huacnlee +1, form 和辅助提示是工作中很消耗的一部分

使用 cancan 的话,基本要遵循 resourse。使用动词或者动词加形容词的组合命名额外 action,这样才能达到使用的目的。不规范的 action 名字,权限控制那些代码读起来简直就是。。。尼玛啊!!这种感觉。。

很讨厌 cancan!

实际上我一开始觉得 RSpec 的优势在于它能够更好的组织测试代码,因为它的变量作用域划分很灵活,加一层 describe 就是一个新的作用域,然后就可以为这个 example group 新写一个 before :each。

嗯……test unit 也能,但是好像大家并没有都在正确的用。后来在用 test unit 的那段时间里,我总觉得如果用 test unit 写测试的话,应该对某个类的每一个功能(方法)分别写一个 TestCase 类,然后再在这个 TestCase 类里遵守 one assertion per test 的原则。而不是把针对整个类的所有方法的测试都塞到一个 TestCase 类里,因为被测类的不同方法需要的 setup, teardown 可能都不一样。把整个类所有方法的测试都塞到一个 TestCase 类里的话,结果测试代码很容易就是一团乱,比如说你需要在测试方法里做一些本来是 setup 做的事。当然也就只是这么想想,没有去打破团队里大家的习惯自己一个人尝试这么干。

所以我后来一直觉得这两个用哪个都无所谓,用好了都一样,用不好……也都一样。

刚和一个老外讨论了 rspec 和 test unit,他说对于一个新手来说,rspec 明显可读性高多了,陌生的东西基本都可以猜出来,而 test unit 就不行。。

我这么喜欢 simple form,你们为啥黑他。

#1 楼 @luikore 你忘了说——ruby

确实……用过 Devise 就觉得有点过重了…… simple_form 我觉得如果页面样式足够简洁……确实可以不用……

Devise 和 simple_form 我 几乎 每个 Rails 项目都用。。。

#20 楼 @fsword ruby 不是 gem 啊

除了 Cells,都准备用的……不是不要重复发明轮子么?不就是冲着不用重复发明轮子这个好处来的么?而这些不是最有名最常用的轮子么?

#1 楼 @luikore 还有 ...

  • rubygem
  • Ruby
  • Web

#25 楼 @chairy11 折腾这些轮子的时间会超过自己写,不过建议你先试一试,自己体验一下。

Devise 确实,自己写也很快

Devise 和 Simple Form 仍然是我的最爱,他们的文档都很棒,常见的需求和问题都非常容易找到。

对于一些业务逻辑相对复杂的应用,simple_form 省事很多。

我对于这些 Gem 的态度是,如果还玩不转,就老老实实造个轮子先。

Devise,看文档的功夫自己都把登陆验证实现了

这让我想起一段话……

但是,当他向曲线上方望去,他不会意识到自己正在看更高层次的语言,而是仅仅觉得自己在看某种奇怪的语言。他可能认为那种语言和 blub 语言一样强大,但是加入了不少怪东西。他觉得 blub 语言已经够用了,不用再考虑那些语言了。这时,他的思维已经被 blub 语言同化了。

下次我如果觉的某个东西“够用了”,不需要 XX 了,虽然别人说 XX 更好——那一定是个危险的信号——除非我想的是“有更牛的一群人说用 OO 比 XX 更好,更符合我的使用场景”,而不是单纯“够用了”

其他情况我没遇到过不好说什么,但是对于这一段,真的没法忍……

当我们想要修改表单的时候,最好的方法是修改 HTML 标签,而不是修改 Ruby 代码。不必要的抽象会增加维护成本

你有真的遇到过这种情景么?修改 HTML 标签的维护成本怎么可能比修改 ruby 代码低……我遇到过好几次了,从 bootstrap2.0 升级到 bootstrap3.0, 从 rails 默认的 server rendering 转到 client rendering,从 jquery-ujs 转移到 angular.js without jquery,再从 angular1.1.5 升级到 angular1.2.1, 各种 breaking change,你可以想像一下这其中修改 HTML 标签和修改 ruby 代码以适应新 api 新 markup 哪个维护成本更高……

#31 楼 @aptx4869 频繁的技术迁移本身有问题,除了 form 别的结构也要有很大变化。

请问一下 @Rei ,你在测试时,使用的 Gem 有哪些?有没有先写测试代码的习惯?我感觉如果用先写测试代码的习惯来思考,感觉 Rspec 更符合思维一些。

#33 楼 @imlcl Rails 常用 FactoryGirl,其他的 FakeWeb 之类看情况用。我是不严谨的 TDD,我感觉 Test::Unit 更符合我的思维一些。可能你学的时候看的例子是 Rspec,所以觉得适合你的思维。

感觉说的有点片面,只是那些 gems 还不那么完美而已,以后一定会更好的。

如果说 轮子 不好用 就不要轮子了,如果说 没有 不好用的轮子呢 .... 当有 圆的 轮子 再造 方型的 估计不会太难 ..

simple_form 还是挺好用的,特别是当有很多 crud 需要做表单的时候。如果是开发好玩的应用,或者 form 不多的,那确实用处有限。

可能用 warden 来代替 devise 会比较好?

Rspec 里面的语法在 JavaScript 里面可以对应 mocha/jasmine + BDD + expectjs/chaijs 等等 在 java 世界可以对应 cucumber framework.

以前的几个项目有要求用 cucumber 来写 selenium testcase, 那个语法+annotation 写下来的效果几乎就和 BA 在 backlog 里面写的需求验收标准一样。

说实在的,不是 native speaker 恐怕没法意识某些老外对代码可读性的洁癖。

#34 楼 @Rei 这么说也有道理哦,我的确是先看到 Rspec。有机会也试试 Test::Unit。Thx

被楼主抢先写了…

基本上我也不喜欢这些 gem,但有的时候懒得自己写,还是用

看来是要去乖乖写 Test::Unit 了 && Devise 坑略多……

Cells 挺好的东西啊,小项目当然用不着,大一点的项目,多个页面共享多块区域时,不用 Cells 会乱成一锅粥

#42 楼 @hooopo 你早说啊,你为什么不早说?你应该早说的啊!

#42 楼 @hooopo #46 楼 @Rei 你俩 在♂一♂起吧。。。

为什么感觉 Devise,Cancan 超好用呢?

#48 楼 @chunlea cancan 超难用...

#17 楼 @yuan context 确实是好东西。minitest 写了两套语法,却没给 Test::Unit 加上 context。

那么见仁见智的问题,觉得没必要说得那么铿锵有力。

#52 楼 @Los 因为相关问题太多了,回帖告诉楼主不要用 XX 又显得不友好。

涉及核心业务 - 自己写 基础设施或者边边角角 -可以考虑用 gems

#50 楼 @Rei

minitest 没有 context,这是超级不爽的地方。

#48 楼 @chunlea cancan 的语法很不习惯。。

除了 RSpec, 其他都不想用

#50 楼 @Rei #55 楼 @xiaoronglv

我刚试跑了一下 minitest,它的 describe 方法好像跟 rspec 的作用一样。

在 rspec 里 context 只是 describe 的一个别名。

匿名 #59 2013年11月23日

这些都用过,不喜欢用 cancan

#58 楼 @yuan 是一样的,因为有个 https://github.com/thoughtbot/shoulda-context ,说 context 比较容易搜到东西。

业务上大包大揽的,基本不会出现在我的 gemfile 里,比如 devise。 写个自己能用的,也就几个文件,几百行代码而已。别人也容易看懂。 自己写一次,以后基本就是 copy+paste 的事情了。

#32 楼 @Rei 我都没说间隔的时间,怎么就能扯到技术迁移的频率了……这几项技术迁移,根本原因是当时我前端太菜了,原来只听说过 rails 默认的 jquery 那一套东西,为了实现需求折腾过各种 jquery plugin,问题在于用 jquery 那套东西根本没办法做出需要的效果,不得不改,现在再让咱开新项目,前端是绝对不可能用跟 jquery 沾边的任何东西了……还好当时因为是从后端转全端,习惯了用 ruby 弄各种 helper 来写 view,多一层抽象改起来反而相当方便

比方说 angular1.2 的其中一项 breaking change 是重写了动画效果,将 ng-animate 指令移除换成 class base,结果我这只需要在后端改几行,前端统一加个动画定义就完事了,view 基本都不需要动:

--- a/app/helpers/animation_helper.rb
+++ b/app/helpers/animation_helper.rb
@@ -18,13 +18,9 @@ module AnimationHelper
    :rotateIn, :rotateInUpLeft, :rotateInDownLeft, :rotateInUpRight,
    :rotateInDownRight, :lightSpeedIn, :rollIn].each do |ani|
      define_method(ani) do |*args|
-       speed = args[0] || ''
-       { 'data-ng-animate' =>
-         {
-           show: "animated #{speed} #{ani}",
-           enter: "animated #{speed} #{ani}"
-         }.to_json
-       }
+       speed = args[0]
+       prefix = speed.to_s.gsub('ani-', '') + '-' if speed
+       { class: "#{speed} a-#{prefix}#{ani}" }
      end
    end

要是没这一步抽象直接写 HTML 估计就得蹲墙角画圈圈了,一百来处动画,生成的 markup 还不怎么带重样的…… form 也是一样,要不是能给 simple_form 打 monkeypatch,20 来个 form 至少一个 field 一个 button 每个 field 一个 error message,原生态 view 改起来,光写 ng-model 就得手抽筋……实际上一个不到 50 行的 monkeypatch 加一行for i in app/views/**/*.slim; do sed -i "s/simple_form/ng_form/g" $i;done就搞定了

#62 楼 @aptx4869 本来自己写个 helper 就好,给 simple_form 打 monkey patch 还不如不用啊

#62 楼 @aptx4869 看来你们以后也不打算把前端交给前端干了。

“不,你不能改 HTML,要改 Patch!” “不不,你不能只改一个 Form!要不全改要不新建一个 Builder。” “为什么你创建那么多 Builder?!”

另外,Rails 本身就能自定义 FormBuilder:

http://guides.rubyonrails.org/form_helpers.html#customizing-form-builders

这些都可以不用,但不可以不学。

#63 楼 @luikore 6 个多月前的事情了,一开始需求简单,先得让程序能继续跑起来,要在每个 field 上面加上相应的 ng-model,于是第一反应就是直接给 simple_form 打了个 monkeypatch,后来更详细的需求定下来后就按照 simple_form 的 Readme 用Custom form builder重构了

#64 楼 @Rei 我们只新建了一个 custm form builder:ng_form,两个 custom input:CodemirrorInput、EditInPlaceInput,根本没有你脑补的情况好嘛,至于直接用 rails 本身自定义的方法,话说 simple_form 难道不就是用 rails 的自定义方法定义好的东西么,我为什么重新再来一遍,一千多行呢,要实现类似效果工作量估计都差不多,还不一定有那么好……

怎么没有人说把 sprockets 移除掉

#31 楼 @aptx4869 这段话非常好,求出处。

但是,当他向曲线上方望去,他不会意识到自己正在看更高层次的语言,而是仅仅觉得自己在看某种奇怪的语言。他可能认为那种语言和 blub 语言一样强大,但是加入了不少怪东西。他觉得 blub 语言已经够用了,不用再考虑那些语言了。这时,他的思维已经被 blub 语言同化了。

有时候,不能理解有些东西的妙处,的确是自己的原因。

#69 楼 @yanhao Hacker and Painters by Paul Graham.

當你一直往上把事情弄得太抽象,就會像上太空一樣沒有氧氣。有時候這些聰明的思想家就是停不下來,然後就創造出這些荒唐又無所不包的高層次宇宙景像,這些東西什麼都好,就是完全沒有實際的意義。

http://local.joelonsoftware.com/wiki/The_Joel_on_Software_Translation_Project:%E6%9E%B6%E6%A7%8B%E5%A4%AA%E7%A9%BA%E4%BA%BA

我觉得这个还是要看使用场景,大多 gem 是为了解决某个领域的通用问题以简化工作量,所以不可能做到绝对高性能。事情不能一竿子打死了。

比如 devise 不但可以加密,还可以记录登陆 IP,最后登陆时间,email confirm,支持 omnioauth 使用,每一个都是对业务很有帮助的特性,一个个写是不是太麻烦了。

cancan 算不上好的权限控制插件,但做复杂权限管理的时候绝对比自己写 before filter 好。而我也更愿意在一个地方管理所有的权限,这就像一个 map view,可以从业务角度更好的看清权限分配是否合理。

个人觉得 simple form 也是个好东西,至少能让我每次都少些很多 tag,适当的配置下又是一套新的结构了。

Rei 我觉的 Ruby China 对新手不太友好 提及了此话题。 07月13日 12:11

写的有道理,建议加到 wiki 里面

RSpec 能做的 MiniTest 都能做,但是 RSpec 代碼真的特別好看…… 而且 MiniTest 現在也不在標準庫裡了,一大優勢沒有了。我反正一直是用 RSpec。

Devise 不能做「前後端分離」的項目,我已經棄用…… 什麼時候做前後端一體的項目,再把他拿出來用。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号