• 终于拜读完了,条理比较清晰,不过觉得有几点或许可以成为建议。

    1. 统计功能其实最容易遇到的就是性能问题,我看你实现统计的代码是每次都从数据库查过去七天的记录,然后再 group by,这块可以建议用一个定时任务每天 0 点之后去统计前一天的数据,最后再把统计结果写到数据库,后边业务上只需要查统计好后的 PV UV 数据就好了,这种方式适合需求比较固定的场景,比如每天都想看过去的 PV, UV, 而且这些数据本来就是静态数据,适合先统计好,原始数据仅作统计结果校验。另一个不建议每次查看的时候去查原始数据的原因是,当你的数据量开始多了之后(几百万甚至几千万),这样的查询可能会明显慢下来。
    2. 看你的描述,如果 Impression 只是用 varchar 存 hash 的话,这样必然没法索引,那这样 impression 其实没太大必要,毕竟这些东西我自己也可以写一个 concern,然后专门提取这些信息然后一股脑塞进数据库就行了。但是这样的话,以后如果需要做一些数据分析的时候就会非常痛苦了,比如哪天运营找你说:“嘿,帮我看看昨天有多少 PV 或者 UV 是从 xx 推广过来的,还有这些里边有多少转化成为新用户”,然后可能过多几天,运营又会找你说:“帮我看看昨天有多少来自广州的用户”。这些场景下,可能结合一些索引工具会更好,比如 Elastic Search、Solr 这些,不过这样又会增加复杂度。或许像你说的 Postgresql 会是更好的选择,又或者 NoSQL 数据库,anyway,只是一个设想,我自己也没实践过。
    3. 你的那些 PV UV 数据或许用图表展示会更直观生动。

    哈哈,说得一般,求轻拍。

  • 先收藏再看,太晚了,得先睡觉了,明天再拜读

  • #12 楼 @jimxl 嗯嗯,是的,主要还是不想写入 nil,至于 nil 出现,那是后面场景需要解决的。

  • #8 楼 @jimxl 你的意思是,与其静默地照样返回 nil,还不如直接抛出异常,然后由调用方去处理异常?比如:

    # active_support
    def save_block_result_to_cache(name, options)
      result = instrument(:generate, name, options) do |payload|
        yield(name)
      end
    
      if result.nil? && !options[:allow_nil]    # :allow_nil is true default to be compatible with original behaviour
        raise ActiveSupport::Cache::NilError
      end
    
      write(name, result, options)
    
      result
    end
    
    # 调用者
    def read_external_service(params)
      # allow_nil: false will force active_support to raise an error when the block return nil
      Rails.cache.fetch 'example_cache_key_here', expires_in: 7.days, allow_nil: false do
        response = HTTParty.get 'https://example.com/example/request/path'
        JSON.parse(response.body)["data"]
      end
    rescue ActiveSupport::Cache::NilError => e
      handler_for_nil_cases(params)
    end
    
  • #5 楼 @billy 哈哈,懒癌发作,还没提交代码,因为还要加上测试,所以看看周末再弄了

  • #3 楼 @jimxl 实际上还是会有异常,因为还是照样返回 nil,只是没有写入缓存而已。

  • #1 楼 @yukang 哈哈,好的

  • #5 楼 @yue 被其他 instances 执行了的话,难道不会在那些 instances 里边触发异常吗?比如找不到类定义之类的。我们现在都是用 database 隔离,不同应用就用不同的 database,从根本上解决问题哈。

  • #10 楼 @chaucerling try 是 active_support 的实现,不是 Ruby 语言层面的实现。

  • #7 楼 @hz_qiuyuanxin 哈哈,同问

  • #6 楼 @goofansu 嗯嗯,以前也遇到过 turbolinks 在安卓版微信浏览器里有奇怪的问题,所以也是关掉了。

  • 手动处理下?

    $(document).on("ready page:load", function(){
      document.title = 'xxxx';
    });
    

    不过还是建议先读下 turbolinks 的源码,检查是哪里出现了问题?是不是 document.title = xxx 的方式不支持?

  • 找下 JSON builder? 比如 jbuilder ?

  • Spree 扩展机制分析 at October 06, 2015

    #2 楼 @tini8 印象中是因为数据库查询都太慢了,我估计 Spree 是想把性能优化任务留给开发者吧

  • 命名空间用 / 表示,你的例子就是:

    zh-CN:
      activerecord:
        attributes:
          system/user:
            name: "名字"
    

    楼上的是正解!

    如果还不清楚,可以看 active record 源码。

  • 诡异的 Node 版本 at October 02, 2015

    楼主可曾知道大明湖畔的 io.js?故事要从很久之前说起。。。

  • OneAPM 简单体验及建议 at September 24, 2015

    曾经试过在已经装了 newrelic 的项目中再装个 oneapm,结果启动服务器时警告 constant initialized,呃,呵呵。

  • #3 楼 @jaylin Rails 的有 Refinery,不过不好用,真心还是 Wordpress 好用

  • Ruby 数组只是一种方法? at September 20, 2015

    #9 楼 @cicholgricenchos 我觉得你这个更多是解释了什么叫鸭子类型,因为你认为实现了下标读写器的类型就是数组,但无法说明数组就是方法。按照这种思路,数组的实现也可以是字典(所有的键是按数字从 0 开始递增),再如果我用链表实现,那么我也可以说数组就是链表。鸭子类型的强大之处就在于你可以专注于你可以做些什么事情,而无需过多担心你的对象到底是什么类型。

  • 期待的是

    Post.where(id: 1).or(parent_id: 3)
    

    像你这段

    Post.where('id = 1').or(Post.where('id = 2'))
    

    我觉得我还不如直接选择用 arel

    posts = Post.arel_table
    Post.where(posts[:id].eq(1).or(posts[:id].eq(2))
    

    不过用 arel 的缺点就是在条件一多的时候就容易一大堆括号。

  • 关于邮箱验证 at September 12, 2015

    #9 楼 @justin 哈哈,是的,其实要写一个完整的还不够,还要考虑原点不在首尾

  • 关于邮箱验证 at September 12, 2015
    /\A[a-zA-Z\.\-0-9][email protected]\Z/
    
  • 关于邮箱验证 at September 12, 2015

    #2 楼 @justin 哈哈,你是顺便打了个广告吗?

  • 关于邮箱验证 at September 12, 2015

    #4 楼 @vincentjiang 你这个是不是少了?比如 [email protected]

  • #2 楼 @vincentjiang 什么错误

  • 跟对象序列化有关吧,可能是将数字序列化错了。