• 你的两个问题其实都由一个问题引起的,就是 Collocation 和 Group 是两个不同的类,但需要统一查询,由此才引起的 where, join, order 一系列麻烦。

    解决方法:使用 STI,让 Collocation 和 Group 都使用一个基类,查询就用基类去查询,你这个应用场景是适合使用 STI 的。

    create_table :base_groups do |t|
      t.string :type, limit: 50
    end
    
    class BaseGroup < ActiveRecord::Base
      has_many :hit
      has_many :sets
    end
    
    class Collocation < BaseGroup
    end
    
    class Group < BaseGroup
    end
    
    class Set < ActiveRecord::Base
      # 也不需要 polymorphic 了
      belongs_to :setable, class_name: "BaseGroup"
    end
    

    其他 scope 什么的该怎么做就怎么做,因为都使用的基类,查询就跟非 polymorphic 的查询一样写。

  • 说说 Rails 的套娃缓存机制 at 2014年09月12日

    @zchar @loveltyoic 原来如此,如果缓存经常失效就失去意义了。这点来看后端缓存非常依赖页面如何展现。如果前后端分离的方式缓存可能影响比较小。后端只操心缓存单条数据,不用去 touch parent,前端也可以按需去加载页面中的数据,而不用一次请求整个页面。

  • 说说 Rails 的套娃缓存机制 at 2014年09月12日

    关于第一个坑,有没有可能把整个 @project 也当成 key 的一部分呢?这样的话就不用考虑要用多少 @project 的 attributes 了。我对 cache 方法不大了解,仅仅一个例子:

    <% cache [:todolists, @project, @todolists.max(&:updated_at)] do %>
    <% end %>
    

    关于第二个坑,缓存对不同类型的用户怎么处理确实是个头疼的问题。有的用户可以看见所有内容,有的用户只能看见他有权限看见的。DHH 的 How Basecamp Next got to be so damn fast without using much client-side UI 讲的方法是仍然 cache 所有人都可见的版本,然后用 JavaScript 去掉当前用户无权看到的部分。也不失为一个简单的方法。做 cache 反而简单了。不需要考虑把当前用户的 role 加入 cache key 或者查询时筛选掉用户看不到的数据之类的。

  • 说说 Rails 的套娃缓存机制 at 2014年09月12日

    :plus1: 赞内容,更赞译名,套娃……

  • @googya 你说了我才看到……做人好低调啊……

  • Vim 上 syntastic 我觉得挺影响速度的,尤其是保存的时候。所以后来索性关了。总的来说 Vim 是有一些杂七杂八的小问题,不过可配置性是编辑器的佼佼者。

  • 表串来串去 at 2014年09月08日

    @Rei 后面的 where 应该不对,生成的 SQL 会是类似 WHERE "users"."role_id" = 1 这种。

    稍微复杂点的 SQL 查询都建议用 Squeel,容易看懂又好维护。

    # 假设你有一个 role object
    User.joins { members.member_roles }.where { members.member_roles.role == role }
    

    好处:不用拼 SQL,也不用操心任何关联的 key,Squeel 会帮你从 relationship 中去找。

  • Devise 里面对密码也是这样比较的,还特地加了注释说是预防 Timing attack,不过到现在都不明白 Timing attack 的攻击原理。

  • Ember 或者其他的前端 MVC 不是 Rails 的一个组成部分,跟 Rails 也没有任何关系。它是在前端提供分层架构的一个工具。就像 @nightire 说的,它的抽象层次比库要高,跟那些提供某种 UI 组件的 jQuery 插件不是一种类型的东西。

    那什么时候需要用 Ember 或者其他前端 MVC 框架?那就是当你的前端代码复杂到需要分层来保持清晰度的时候。拿后端的 web 开发举例子,要写一个简单的网页,你可以用 PHP 直接做,不需要任何分层架构,你可以不要 model 把 SQL 写在页面上,也可以没有任何 controller 逻辑,只要你的需求足够简单。但如果你要做一个完整的 website 这样你会疯掉的。前端是同样的道理。

    当你的前端复杂到工程级别时,你自然会需要一个单独的框架去帮你处理架构问题。否则用 jQuery 就挺好。

  • 喜欢 CoffeeScript 就几个原因:

    1. 和 JavaScript 贴的最近,仅仅是改进了一些 JavaScript 的繁琐的地方,加了少许新特性。LiveScript, TypeScript 和 Dart 都引入了太多东西了。
    2. 不需要 jshint 之类的检查工具去辅助 JavaScript 检查错误。

    长期来看我还是支持 JavaScript。这些编译成 JavaScript 的语言都面临一个问题,就是跟 ES6 的语法冲突。 有些语法像 ->, xxx for in, for ... of ..., class 在 ES6 里面也有,但 CoffeeScript 自己也定义了一套。LiveScript 的 let 在 ES6 里面也有。那写这些代码的时候,编译器是应该尊重 ES6 的语法,还是用自己的理解编译成 ES5 呢?尤其是某些语法在 ES6 和在 CoffeeScript 中的理解不一样的时候。

    一个关于 CoffeeScript 和 ES6 的讨论可以见 Discourse 论坛的这篇讨论 。这也是为什么 Discourse 用 JavaScript 全部替代 CoffeeScript 的原因。当然他们这样做还有一个原因:对于开源软件来说受众更广泛的 JavaScript 能吸引更多的 contributors。不过那就不在语言讨论范围之内了。

  • 4.x 最后一个大更新,下一个就是 5 了。

  • @HungYuHei @Rei Python 的哲学是“解决问题有一个唯一的最优方法”,而 Ruby 崇尚“有很多种不同的方法可以完成一件事”。结果 Ruby 总是只有一个主流版本,Python 现在还在 2 和 3 之间各种纠结。

  • PostgreSQL 还是蛮强大的,除了 array 和 hstore 外还可以直接支持 json,简单的嵌套数据和少数的可变字段都可以存到 json 里面去。

  • CoffeeScript 拼接多行 HTML 无压力

    text = 'Hello World'
    page = """
      <div>
        <h1>#{title}</h1>
      </div>
    """
    

    编译结果:

    var page, text;
    text = 'Hello World';
    page = "<div>\n  <h1>" + title + "</h1>\n</div>";
    

    <div> 之前的空格都给你自动省略了,它知道是为了代码缩进。

    简单的情况一般就拼字符串凑合,复杂的情况用 template engine 更可靠,毕竟语法支持多一些,还能处理字符串注入。

    PS: ES6 马上也有嵌入字符串功能了。

    var text = `Hello ${'World'}`;
    
  • 我倒觉得 model 层 validation 没通过就足够了,返回的 error message 也可以直接展示在页面上。 而且 Form object 层的 validation。一部分我觉得可以用 valid?(context) 去做。

    class User < ActiveRecord::Base
      validates :email, uniqueness: true
      validates :address, presence: true, on: :sign_up  # 只有 sign up 需要做的验证
    end
    
    class SignupForm
      def submit(params)
        if user.valid?(:sign_up)
          # ...
        end
      end
    end
    
  • @huacnlee @hooooopo 跟知乎一样也有转型成大型情感交流社区的节奏?

  • @Peter 我的理解,这就只是一套规范,没有具体的框架给你用(也许会放到 SDK 里面成为默认组件?),也不需要强制遵从。毕竟 Android 的开放性摆在那里,连第三方 Store 都可以随意建,Google 不会也没办法去像 Apple 那样约束软件开发者。

  • @saiga 没有现在的 Google Design 完善,而且细节上是有区别的。比如 Nexus 5 联系人应用里面的 text field 底线是两边带有一点翘起的细线,类似平躺的 "[" 号。现在就是简单的一条横线。

    本来我是想做成那样的,但需要额外的 HTML 标签,对 mobile app 来说太浪费了,而且还得考虑 iOS 版接不接受这种风格,所以就简化成了一条底线…… 然后发现 Google 现在也减了~

    Google 这次的设计是想统一制定手机,平板,笔记本所有设备的 UI 规范。我觉得那套 UI 设计看上去还挺不错的。

  • @debugger 后面两个图就是啊。是公司的项目,不是开源的,所以没法放上来。 @stephen PhoneGap 加一些 web 技术做的。HTML, CSS 自己弄的,JavaScript 用的 Ember.js

  • 我也碰到了这种问题。目前想来,拆成两个项目会更好,如果你有时间折腾的话。

    拆开大概面临的问题是,HTML, CSS, JavaScript 全部放前端项目。也就是说 bootstrap-sass 这样的东西不需要靠 Rails 来装了。带来的问题当然就是 asset pipeline 完全用不着了,所以你得用其他的方式来做它所提供的功能:

    1. SASS 的合并,JavaScript 压缩,这个还算好办。
    2. 为压缩后的文件加 fingerprint,这个还涉及到 HTML,Node 里也有插件可以实现。
    3. SASS 文件里的 image-url,估计也可以用 Compass 无缝过渡。

    从长期来开,如果前端本来就很重,分开是个很好的选择,我觉得也是必须要走的一步。从此 Rails 可以更轻松。不需要 view 和 helper 了。测试到 Controller 层为止,不过还得加一层 Serializer,处理 JSON 数据。

    我在想一个不用完全分开的过渡方案,大概就是 CSS 和 image 还是用 Rails 的 asset pipeline,先只把 JavaScript 分离出去。目前能够想到的方案:

    1. 单独开一个目录存 JavaScript 文件,
    2. 用 Node 的工具(Grunt, Gulp, Broccolli 等)合并成一个文件,然后 copy 到 app/assets/javascripts/application.js
    3. Rails 端什么都不用改,HTML 模板里面 javascript_include_tag 'application' 就完了。
    4. 部署的时候用 Rails asset pipeline,Rails 会自动给 application.js 加上 fingerprint。
    5. JavaScript 测试的话,单元测试完全够用了。

    缺点是 application.js 需要放到版本库中去,而且每次开发需要开一个 Rails server 和一个 Grunt 任务。这个方案相当于一个半吊子前端项目(只处理 JavaScript)和 Rails 项目的整合,只是平滑过渡用。

  • 开源绘图软件 Krita 募捐中 at 2014年06月23日

    @Rei 9000 那张画原型是赛亚人么?

  • ActiveRecord 真的是 ORM 吗? at 2014年06月22日

    @zacker330 你说的对,只要不固执的认为自己以前的全是对的,也不排斥新知识。 不知道你以前看的什么书学 Rails,如果觉得那些书都不能解答你的问题,就去看 Rails Guide 吧。关于你这个问题(ActiveRecord 和 ORM)里面都有很详细的解释,包括 ActiveRecord 的设计哲学。

  • ActiveRecord 真的是 ORM 吗? at 2014年06月22日

    不要用已有的经验去揣测未知的东西,尤其是学新知识的时候。

    你最开始的疑惑在于 Rails 为什么把表结构定义放在 db/schema.rb 里,因为你有个概念“ORM 是关系和结构都定义在一个地方”,至少是觉得 ORM 需要定义关系和结构。但 Rails 的 model 恰恰不需要你定义结构。你完全可以自己用 SQL 生成数据表,然后建立一个空 model,这完全可行。不需要建立 migration,不需要改 db/schema.rb

    CREATE TABLE projects ( name varchar(30) );
    
    class Project < ActiveRecord::Base
    end
    
    project = Project.new
    project.name    # 不需要定义 name 属性,ActiveRecord 帮你生成
    

    如果你执着于 ORM 需要你定义结构这种概念,那肯定会百思不得其解,然后到处去找 Rails 又生成了什么文件去定义结构…… 也许 Google 一番后你会知道这是因为 Rails 会按约定去扫描对应的数据表 projects 从而自动生成 model 属性。而这样设计的初衷正是为了让开发者不需要因为更新数据表而频繁修改 model。

    然后你会发现不是 ORM 需要你定义结构,只是你以前用过的一个或者一些 ORM 需要你定义结构而已。但这时你已经绕了一个圈子了。

    至于 db/schema.rb 和 migration 文件,那是给你方便地修改数据库结构的工具。楼上的各位已经讨论的很清楚了,就不掺合了。

    最后引用一段话,来自 Rails Guide 的 ActiveRecord 章节:

    When writing applications using other programming languages or frameworks, it may be necessary to write a lot of configuration code. This is particularly true for ORM frameworks in general. However, if you follow the conventions adopted by Rails, you'll need to write very little configuration (in some case no configuration at all) when creating Active Record models. The idea is that if you configure your applications in the very same way most of the time then this should be the default way. Thus, explicit configuration would be needed only in those cases where you can't follow the standard convention.

    建议你学习 Rails 以 Rails Guide 为主,应该可以解答大部分的新手问题。

  • 对于大的分模块的项目,进行 migration 文件归类管理确实很有必要。不过对中小型项目而言这种目录结构太复杂了。

    我以前也喜欢删旧的 migration,尤其是加了字段然后又删了的情况。后来觉得这样挺折腾的,还要去服务器上删除 scheme_migrations 里面的记录,要是有 staging, production 等多个服务器还要麻烦,只是心里觉得干净了一些。现在的项目试着完全没有管旧的 migration,任何一个小的修改都开 migration 去做,感觉维护还更方便了,什么都不用操心。

    BTW,自从换了 Sublime Text 之后,我发现多了一个看 migration 的方法,直接用 cmd+p 模糊匹配 migration 文件,只要文件名遵从一定的规律,查找起来也挺方便,加上切换文件即时预览,也够用了。

  • @dddd1919 public & private key 是更安全也更方便的办法。 term_mode 我貌似以前用过一次,当时会导致 deploy 的输出排版乱了(缩进没有了,高亮没了),恰好我用 mina 最大的理由就是输出比 capistrano 整洁…… mina 只是对简单的部署情况适用的,所以没考虑那么多东西,按照标准的流程来,省时省力又少折腾。

  • 不是急着用就等一段时间呗,急着用就出手好了。就像 @lgn21st 说的,如果只是配置升级,那真没什么好纠结的。目前的够用了。早买早享受。

  • ratchet 是做原型的,试用了一下后觉得还有点欠缺,如果开发 Hybrid app 可以试试 Ionic。印象比较深的是 Ionic hack 得比较厉害,连 scroll 都是用 -webkit-transform 做的。在 Chrome 上调试不支持 click 事件(不过作为 Hybrid app 也没必要支持,只是平时开发稍微有点不方便而已)。 另外前段时间发现一个 Onsen UI ,做的也不错。如果是 Hybrid app,Ionic 和 Onsen UI 取一个就行。Web app 就随意吧。

  • 响应式布局加入 at 2014年05月26日

    :plus1: 是说打开页面觉得变宽了,能更好的利用屏幕尺寸了。

  • 纠结是继续折腾 Vim 还是折腾 Sublime。Sublime 除了速度快,像 system, user, project 三层 settings 这种内建进编辑器的特性对我来说也很有用。特性内建进编辑器意味着所有 plugin 都会支持。这个比 Vim 要方便很多。

  • @iBachue 现在在学 Sublime,主要是它确实快。搜索很方便。听你说这话我又有点纠结了。