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

    @zacker330 我还真的不是从数据库开始思考的诶 :)

    打比方如果写或者维护 ruby-china,那脑子就全部都是 Post, User, Comment。之间的关系都是 User has many comments, comment belongs to user。而不是 comments 表有一个 user_id 字段等等。

    又比如说 repository model(我不知道具体的写法,只是假想),User 有一个 github repos 的数据,那么我就知道 User has many repos。至于这个 repos 是存在数据库里,还是直接从 github 获取,都不影响别的 model 和它直接的关系。

    另外一个,schema.rb 是不能自己修改的。推荐的方法是通过 migration 来修改。

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

    Martin Flower 的定义很明确啊

    An object that wraps a row in a database table or view, encapsulates the database access, and adds domain logic on that data.

    楼主的思维方式可能要改变。你是从数据库开始思考问题的。而一个应用应该是以 model 为中心思考。储存在数据库里只是 model 的一个存储方式而已,model 的存储也可以在内网其他应用,也可以是外部 API,也可以是一个文本文件,可以存在于很多地方。

  • 正确的做法是

    1. 加多 CSS 标签。既不要针对 id 做样式,也最好不要轻易改动框架默认。

      <div class="row top" id="a">
      <div class="row bottom" id="b">
      
    2. 给新 CSS 标签设置样式

      .top { margin-bottom: 10px; }
      

    用 br 也是不可取的,如果你没有耗尽 CSS 的可能,就不要用 HTML 标签做样式。HTML 标签应该更多用在语义上。br 在这里没有任何语义。

  • bash 怎么会加载 zsh?你进入 zsh 应该在 console 里面直接设置而不是调整~/.bashrc 啊 :)

    什么都不行就用系统自带的 GUI 文本编辑器吧,先把.bashrc 和.zshrc 纠正好了。

  • bash
    vim ~/.zshrc
    
  • 元编程里的一句话 at 2014年06月20日

    @ane, 这个不算。public method 里面可以随意使用 private methods, 毕竟 private methods 的主要目的之一就是为了 public methods 服务的。你可以直接def call_pri; pri; end,都没有必要 send。

    我觉得你没有必要为了这一句话纠结,等看到了具体代码部分再详细讨论比较有价值。

  • /posts 直接到 PostsController#index,是 posts 列表,不是具体的哪个了。

  • params[:post_id]就会告诉你他们在哪个 post 下面。这个参数是在路径里面的 /post/:post_id/comment/:id

  • 看看是不是 secrets.yml 里面哪里把 tab 当成空格了。要是用 vim 就:/s\t查找。

  • meta programming 在这里有些滥用了

    要是就那么几个简单设定,没有任何 association 的话不如直接写在程序 yml 里作为设定,没有必要进入数据库。

    要是你的应用类似于建站工具,每个用户都有设定的话,可以把所有 setting 作为一个字段 serialize,然后直接从 hash 里面取任何值。

  • @bwlinux 好啊,问题被发现了:)测试的时候一切外部网络依赖都应该被 mock 掉,如果比较复杂的外部 API 还可以用 VCR gem。

  • @wcc526 哦,知道你碰到的问题了,你用的默认 TurboLinks 吧。这种情况你应该把所有的函数放到一个函数下 面,比如 init(), 然后

    $ -> 
      init()
    
    TurbolinkPageTransitionEventWhichIForgetExactMethod ->
      init()
    

    原因是你在 TurboLink 下面转页面时没有 document ready 这个事件,所以你之前写的函数不起作用。

    具体 TurboLink event 用法你可以查文档,我好久没用不记得了

  • Best practice 就是,除非你指定页面的 Javascript 文件非常非常大,否则都放在 application.js 里面一起打包。

    指定页面如果要加大库,比如 Google map, D3 之类,可以用异步载入。其他自有文件都可以在打包里面。

    至于函数名冲突,那是你写 JS 的问题。应该改进写法,不能用改变载入的方法解决。

    如果你实在要区分页面载入,可以这么写

    <%= javascript_tag "foo.js" if controller.name == 'foo' && action == 'index' %>
    

    很难看就是。而且 performance 一般只有轻微劣势,没有优势。

  • 这个从逻辑上来说也不难。试一下吧。

    首先建一个新 model, ContiniousLogin, 对应表 continious_logins。或者放在 yml 里面

    然后做一个 rake task 或者 job

    User.find_each do |user|
      last_login_day = nil
      days_count      = 0
    
      Login.find_each(name: user.name) do |login|
        current_day = created_at.to_date
        last_login_day ||= current_day
        prev_day = current_day.prev_day
    
        if prev_day == last_login_day
          last_login_date = current_date
          days_count += 1
        elsif prev_day > last_login_day && days_count > 0
          ContiniousLogin.create!(name: name, last_login_day: last_login_day, days_count: days_count)
          last_login_day = nil
          days_count      = 0
        end
      end
    end
    

    逻辑大致如此,代码只做参考 :)

    find_each 是每一千个一批次的,也可以调整批次大小,所以数据多少应该影响不大。当然如果时间太长可能就要另说了。

    做实验时可以不用新建 model,用一个 yml 代替也行。总之有个 io 来存记录就好了。

  • 我没有研究这部分的代码,但我对创建 test db 时要读取 development db 的内容表示质疑。应该是读取 schema.rb 就可以了。如果都要读取 development db 那 CI server 就没法跑了。

  • 能给个理由 development db 为什么非要在远程吗?

  • 当还有一堆 migrations 还在维护的时候,这个 gem 看起来很清爽。每个 model 的演化进程都很清楚。

    但是有几个问题:

    1. rollback 和 migrate 能否正常运行?这里没有测试来保证。

    2. 按时间戳的维护变困难了。就像@leozwa@rainchen 说的,定期清理完全不需要的 migrations 也是 Rails good practices 之一。但现在 migration 不按时间排列,很难决定哪一截是需要和不需要的。

    我提供两个思路来解决#2

    思路一:提供一个 rake task 来按时间戳排列。但文件多可能很耗时间,且看不到文件细节。

    思路二:完全放弃这个 gem 而采取一种新的思路。 这个 gem 的是按 model 或 namespace 查看。那么,直接做一个 rake task 是不是也能达到同样目的呢?

    比如这些假想的 tasks:

    rake migration list Post 这个就会列出所有 posts table migrations 文件。

    rake migration view Post 这个就把所有 posts migrations 输出到 stdout 来观看。

    这样的话,migration 还是不动,但多了些手段来方便查看,达到类似这个 gem 的目的。

  • • 明白自动测试比手动测试要好。

    • 明白手动测试比自动测试要好。

    到底你觉得哪个好啊

  • @lgn21st 明白了,多谢!

  • @huacnlee 不是的。貌似楼主以前是用的 Python 图标做头像所以一楼才说的。

  • 话说@xiongxin8802 的建议也太烂了,难道 Ruby 社区就要人人用珠宝头像?

  • 那就用一个子域名来放静态,不带 ssl 的。怎么样?

  • 用 CDN? 靠谱不?

  • 楼主放轻松,那两个帖子内容确实是少了点。爱社区就多放点干货啊。

  • @chenge Hash.new {|h,k| h[k] = [] }返回的值虽然也是{}, 但这个设计可以保证每一个不存在的 key 都会返回一个空 array, 而不是 nil

    h = Hash.new {|h,k| h[k] = [] }
    #=> {}
    
    a = {}
    #= {}
    
    h == a
    #=> true
    
    # 下面差别出来了
    h["foo"]
    #=> []
    
    a["foo"]
    #=> nil
    
  • 嵌套表 edit 时候问题。 at 2014年06月17日

    edit 和 new 难道不是同一份 partial?为什么会有区别?

  • @ywjno 你把数据库和 API 看成同样的东西就好了啊。MongoLab, 还有 Heroku 里面那些 MongoDB 的服务不都是 API 的形式?

  • @wcc526 就像你说的,确实不合理。应用是应用,数据是数据,两者不能混在一起。如果是 assets 图片,那么也是应用的一部分,可以在一起。如果是数据类型的图片,那就不太合适。

    这个情况,如果是图简便的话,也可以这么做:

    1. Rails .gitignore 里面先忽略数据文件夹,比如/data
    2. 建立 root/data/images/, 放入你的图片。如果愿意可以在这里新建 git
    3. 新建一个 Capistrano 任务,不跟随 deploy 启动,而是手动执行。任务内容是把 root/data/images 复制到服务器相应目录,比如 public/uploads/images。