<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>warmwind (姜鹏)</title>
    <link>https://ruby-china.org/warmwind</link>
    <description>金数据</description>
    <language>en-us</language>
    <item>
      <title>[成都 / 西安] 金数据招聘 Rails 工程师</title>
      <description>&lt;p&gt;金数据又开始招聘了，这次我们需要 4 名 Ruby/Rails 工程师，你可以选择工作在 成都或者西安。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;过去 8 个月&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;距离&lt;a href="https://ruby-china.org/topics/33464" title=""&gt;上一次招聘&lt;/a&gt;过去了 8 个月，从达到盈利到扩大盈利，从 27 人到 35 人，从国内年会到&lt;a href="https://mp.weixin.qq.com/s/X2rVwWE3KagGGkViJ2CZmg" rel="nofollow" target="_blank" title=""&gt;集体普吉出游&lt;/a&gt;，从团队内的周年庆到与用户一起欢聚，我们在稳步成长，实现着对自身和社会的承诺。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/2018/69d2778e-b495-4f79-8f6a-3a0de6d83cb8.webp!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;技术栈&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;过去 5 年，金数据经历了 Rails3，Rails4，到现在 Rails5，去年还引入了 React，GraphQL，Cassandra，Ionic(Angular) 等，这些技术的演进将帮助金数据走向下一个 5 年。另外，为了维护平台的纯净，保证所有用户的共同利益，我们也拥抱 Python，使用机器学习，结合 Rails 一起来进行表单的鉴定，感兴趣的同学可以看看去年 RubyConf 上的分享 &lt;a href="https://ruby-china.org/topics/34176" title=""&gt;金数据是如何鉴黄的&lt;/a&gt;。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;如果你的 Rails 经验较少，那么希望你热爱 Rails 的哲学，理解 web 开发的原理，享受写代码带来的成就&lt;/li&gt;
&lt;li&gt;如果你的 Rails 经验较多，那么希望你对于高质量的交付、具有挑战的性能优化、可拓展的建模设计有满满的热情&lt;/li&gt;
&lt;li&gt;如果你更专注前端技术，那么我们提供一个使用 Ionic 和 Angular 进行手机开发的 Junior Developer 职位，不过只在成都&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;薪资福利&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;即便工作在二线城市，金数据的薪资瞄准北上深一线城市。我们薪资福利的目标是让你放下与其他城市的比较，安心的投入工作。我们对于谈判阶段压榨工资没有兴趣。我们看重的是长期的关系，而非一朝一夕的分厘。我们会不断评估你的能力、成长、贡献，每年主动调整你的薪资到更有竞争力的位置。&lt;/p&gt;

&lt;p&gt;其他的福利：&lt;/p&gt;

&lt;p&gt;午餐补贴 / 水果零食
1-3 个月年终奖
半年一次团队 Retreat
所有国家假日的周末调休全部放假
每年一次免费体检
五险一金
补充医疗保险 + 子女医疗保险 + 人身意外险 + 交通意外险
每年 4000 元「Learn Something New」培训经费，可用于任何可以提升自己的活动&lt;/p&gt;

&lt;p&gt;与小金一起成长是我们对每个伙伴的期望，不用担心现在自己还不够强大，在这个过程中，会有足够的机会来提升和施展自己的技能。
发送简历到 &lt;code&gt;talent@jinshuju.net&lt;/code&gt;，小金欢迎你！&lt;/p&gt;</description>
      <author>warmwind</author>
      <pubDate>Tue, 06 Mar 2018 18:44:07 +0800</pubDate>
      <link>https://ruby-china.org/topics/35181</link>
      <guid>https://ruby-china.org/topics/35181</guid>
    </item>
    <item>
      <title>[RubyConfChina2017 话题分享] 金数据是如何鉴黄的</title>
      <description>&lt;p&gt;&lt;a href="https://www.slideshare.net/pengjiang9465/ss-79917770" rel="nofollow" target="_blank" title=""&gt;slides&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="embed-responsive embed-responsive-16by9"&gt;&lt;iframe class="embed-responsive-item" src="//www.youtube.com/embed/rkvL4FHZg7E" allowfullscreen=""&gt;&lt;/iframe&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;这次分享的目的是：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;针对完全没有机器学习或者高等数学基础的同学，介绍机器学习在文本分类领域的使用&lt;/li&gt;
&lt;li&gt;如何无缝对接到现有的系统中（不用修改现有系统一行代码）&lt;/li&gt;
&lt;li&gt;活跃下现场气氛 &lt;img title=":sweat_smile:" alt="😅" src="https://twemoji.ruby-china.com/2/svg/1f605.svg" class="twemoji"&gt; &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;我的微信号是 &lt;code&gt;forsea001&lt;/code&gt;，现场时间有限，想多聊聊的童靴也可以加微信~~（请备注 RubyChina）&lt;/p&gt;</description>
      <author>warmwind</author>
      <pubDate>Tue, 19 Sep 2017 11:58:57 +0800</pubDate>
      <link>https://ruby-china.org/topics/34176</link>
      <guid>https://ruby-china.org/topics/34176</guid>
    </item>
    <item>
      <title>Rails 中消失的 CSRF token</title>
      <description>&lt;p&gt;&lt;a href="http://guides.rubyonrails.org/security.html#cross-site-request-forgery-csrf" rel="nofollow" target="_blank" title=""&gt;CSRF&lt;/a&gt;(Cross-Site Request Forgery) 是一种常见的攻击手段，Rails 中下面的代码帮助我们的应用来阻止 CSRF 攻击。&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ApplicationController&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActionController&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;
  &lt;span class="c1"&gt;# Prevent CSRF attacks by raising an exception.&lt;/span&gt;
  &lt;span class="c1"&gt;# For APIs, you may want to use :null_session instead.&lt;/span&gt;
  &lt;span class="n"&gt;protect_from_forgery&lt;/span&gt; &lt;span class="ss"&gt;with: :exception&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这段代码是 Rails4 自动生成的，这里使用了&lt;code&gt;with: :exception&lt;/code&gt;设置了对在&lt;code&gt;handle_unverified_request&lt;/code&gt;使用的策略是抛出异常&lt;code&gt;ActionController::InvalidAuthenticityToken&lt;/code&gt;。Rails3 中默认使用的&lt;code&gt;reset_session&lt;/code&gt;。
Rails 防止 CSRF 的机制是在表单中随机生成一个 authenticity_token，同时存储于表单的隐藏域以及当前的 session 中，当表单提交时，而 server 端就可以比较这两处的是否一致来做出判断，判断请求的来源是否可靠，因为第三方是无法知道 session 中的 token 的。&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Sets the token value for the current session.&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;form_authenticity_token&lt;/span&gt;
  &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:_csrf_token&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||=&lt;/span&gt; &lt;span class="no"&gt;SecureRandom&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;base64&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"margin:0;padding:0;display:inline"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"utf8"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"hidden"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"✓"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"authenticity_token"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"hidden"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"EZWDs44j5vzY+DCsgTHL0iPYiOUwaFnemwtGmo2AVRM="&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;当然，这些都是正常情况，当表单要作为 ajax 提交，也就是&lt;code&gt;data-remote=true&lt;/code&gt;时，情况就不同了，默认配置下，&lt;code&gt;authenticityt_token&lt;/code&gt;不再自动生成。如果是 Rails3 就会发现 session 中的信息不见了，如果是把 user_id 存储在 session 中的，当然登录的状态就改变了。如果是 Rails4，默认就会得到上面提到的&lt;code&gt;InvalidAuthenticityToken&lt;/code&gt;异常。&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;#form_tag_helper.rb&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;html_options_for_form&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url_for_options&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify_keys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tap&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;html_options&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
     &lt;span class="o"&gt;...&lt;/span&gt;
     &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;html_options&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"data-remote"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
        &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;embed_authenticity_token_in_remote_forms&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
        &lt;span class="n"&gt;html_options&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"authenticity_token"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;blank?&lt;/span&gt;
       &lt;span class="c1"&gt;# The authenticity token is taken from the meta tag in this case&lt;/span&gt;
       &lt;span class="n"&gt;html_options&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"authenticity_token"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
     &lt;span class="k"&gt;elsif&lt;/span&gt; &lt;span class="n"&gt;html_options&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"authenticity_token"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
       &lt;span class="c1"&gt;# Include the default authenticity_token, which is only generated when its set to nil,&lt;/span&gt;
       &lt;span class="c1"&gt;# but we needed the true value to override the default of no authenticity_token on data-remote.&lt;/span&gt;
       &lt;span class="n"&gt;html_options&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"authenticity_token"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;
     &lt;span class="k"&gt;end&lt;/span&gt;
   &lt;span class="k"&gt;end&lt;/span&gt;
 &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;上面代码的 5-14 行可以看到生成 token 时的配置判断，从中也可以得到解决的两种办法：
1. 配置&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;config.action_view.embed_authenticity_token_in_remote_forms = true
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2. 通过 JS 获取
其实在默认的 layout 中，一般会有一行&lt;code&gt;&amp;lt;%= csrf_meta_tags %&amp;gt;&lt;/code&gt;，它的定义是：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;csrf_meta_tags&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;protect_against_forgery?&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'meta'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:name&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'csrf-param'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:content&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;request_forgery_protection_token&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'meta'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:name&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'csrf-token'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:content&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;form_authenticity_token&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;html_safe&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;它在页面的 head 中增加一个&lt;code&gt;csrf-token&lt;/code&gt;的属性&lt;/p&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;meta content="authenticity_token" name="csrf-param" /&amp;gt;
meta content="VY13wlC2rgGccbkxyvm7Z1WX4LKH+71vzIj+8Um0QO8=" name="csrf-token" /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这与表单渲染出的 authenticity_token 完全一致，所以这就给了我们通过 js 来给表单设置 authenticity_token 的办法，如下&lt;/p&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//application.js&lt;/span&gt;
&lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;input[name=authenticity_token]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;val&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;meta[name=csrf-token]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;attr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;content&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;</description>
      <author>warmwind</author>
      <pubDate>Wed, 01 Oct 2014 23:45:00 +0800</pubDate>
      <link>https://ruby-china.org/topics/21821</link>
      <guid>https://ruby-china.org/topics/21821</guid>
    </item>
    <item>
      <title>Rails 3.2 升级到 Rails 4 中遇到的问题</title>
      <description>&lt;p&gt;很久一段时间以来，我们使用的都是 Rails3.2 + Mongoid3，虽然 Rails4 发布已经快一年的时间了，但由于 mongoid3 不能支持 Rails4，所以升级就一推再推，不过终于在近期 Mongoid 发布 4.0 以后完成了这次期盼已经的升级。心情是兴奋地，不过过程还是曲折的，不少细节，只看升级文档，或者 google，不看源码还是真心不好解决。本文不是升级指导，因已经有很多文章，本文将对这次升级遇到的问题做个简单的介绍，包括了 Rails，Mongoid，Capistrano。&lt;/p&gt;

&lt;p&gt;每次升级有两个前提必须保证才可以稍微顺利一些：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;完备的测试&lt;/li&gt;
&lt;li&gt;通读官方&lt;a href="http://edgeguides.rubyonrails.org/upgrading_ruby_on_rails.html" rel="nofollow" target="_blank" title=""&gt;升级文档&lt;/a&gt;。当然升级基本完成后才发现因为已经有 Rails4 已经有一年的时间，网上其实有不少可以参考的其他人的文章，中英文都可以，还有好心人翻译了国外的博文。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;1. Strong Parameters
它主要用来增强 mass assignment 的安全性，Rails3 中通过使用 attr_accessible 在 model 层面进行控制，没有声明为 attr_accessible 的属性不能用 mass assignment 来赋值。但通常来说这个赋值的行为发生在 controller 级别，所以 Strong Parameter 将这样行为的限制上升在 controller，并通过下面的格式来进行限制。&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;permit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:emails&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[]},&lt;/span&gt; &lt;span class="ss"&gt;:friends&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;:family&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="ss"&gt;:name&lt;/span&gt; &lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="ss"&gt;:hobbies&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;}])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这其中定义了三种格式的参数类型，其中期望 emails 的值为 Array 的类型，而 friends 是一组 Array 的资源，有 name 属性，family 的值为 Array 并含有 name 属性，hobbies 的值则是 Array 类型。&lt;/p&gt;

&lt;p&gt;2. controller 测试异常缓慢
我们使用的 MiniTest，升级完成后运行 controller 测试时，非常非常的缓慢。后来发现当测试中 request 请求成功后，停在了在 render layout 那这一步，需要将近 5 分钟才可以完成。测试本身是成功的，而这 5 分钟也与 asset precompile 的时间类似。&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Rails 4 no longer sets default config values for Sprockets in test.rb, so test.rb now requires Sprockets configuration. The old defaults in the test environment are: config.assets.compile = true, config.assets.compress = false, config.assets.debug = false and config.assets.digest = false.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;其中最主要的设置为&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Don't fallback to assets pipeline if a precompiled asset is missed&lt;/span&gt;
&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;此项设置的主要目的是当找不到 precompiled 的 asset 时是不是需要时时编译。当然，我们是不需要这样的设置的，所以当设置为&lt;code&gt;false&lt;/code&gt;时就解决了这个问题。
&lt;strong&gt;不过有个问题还是不明白，之前的默认值为&lt;code&gt;true&lt;/code&gt;是如何正确工作的呢？&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;3. 测试单独通过，rake test 失败
使用 rake 运行所有测试时，抛出&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;TypeError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;compared&lt;/span&gt; &lt;span class="n"&gt;with&lt;/span&gt; &lt;span class="n"&gt;non&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;module&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;无法定位是什么问题，好在有人遇到了一样的问题 &lt;a href="https://github.com/freerange/mocha/issues/199" rel="nofollow" target="_blank" title=""&gt;https://github.com/freerange/mocha/issues/199&lt;/a&gt;,不要使用 ruby2.0.0-p0，改为 2.0.0-p353 就好了。&lt;/p&gt;

&lt;p&gt;4. Capistrano
原先使用的是 Capistrano2，由于 Capistrano3 做了很大的改动，所以为了平稳尽快完成 Rails 的升级，对 Capistrano 尽量做到最小的改动，&lt;a href="https://github.com/capistrano/capistrano/wiki/Upgrading-to-Rails-4#asset-pipeline" rel="nofollow" target="_blank" title=""&gt;这篇文章&lt;/a&gt;一定要看。其中两点最重要：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;升级到 2.15.4&lt;/li&gt;
&lt;li&gt;将 manifest.yml 从 shared/assets 目录移到 releases，并重命名为 assets_manifest.yml，否则部署时会报错说有重复的 manifest 文件&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;需要注意的是，升级之后在部署过中可能会看到一些 err 输出，实际上是 Capistrano 将 info 的输出信息作为 err 打印到 console 了。参见这里&lt;a href="https://github.com/capistrano/capistrano/issues/625" rel="nofollow" target="_blank" title=""&gt;INFO messages while asset precompiling treated as errors&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;5. 嵌入的支持
Rails4 会在 response 的 header 里增加一下的默认值，其中&lt;code&gt;SAMEORIGIN&lt;/code&gt;限定了 iframe 在同一个 domain 中可以使用。如果取消这一限制有两种做法，一个是在下面的全局配置中将&lt;code&gt;X-Frame-Options&lt;/code&gt;改为&lt;code&gt;ALLOWALL&lt;/code&gt;。当然，如果只想针对单个请求，可以将这个设置在该请求的 response 中去除&lt;code&gt;response.headers.except! 'X-Frame-Options'&lt;/code&gt;。&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;action_dispatch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;default_headers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="s1"&gt;'X-Frame-Options'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'SAMEORIGIN'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="s1"&gt;'X-XSS-Protection'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'1; mode=block'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="s1"&gt;'X-Content-Type-Options'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'nosniff'&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;6. Mongid 中使用 Only 后的限制
升级 Mongoid4 后，使用 Only 后的 model 对象将为只读，不可以再修改，否则会抛出下面的异常。检测 document 是否为只读可以直接在 model 上调用&lt;code&gt;readonly?&lt;/code&gt;。在 Mongoid3 中没有这样的限制&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Mongoid&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Errors&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;ReadonlyDocument&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="no"&gt;Problem&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="no"&gt;Attempted&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;persist&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt; &lt;span class="s1"&gt;'Entry'&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="no"&gt;Summary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="no"&gt;Documents&lt;/span&gt; &lt;span class="n"&gt;loaded&lt;/span&gt; &lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;database&lt;/span&gt; &lt;span class="n"&gt;using&lt;/span&gt; &lt;span class="c1"&gt;#only cannot be persisted.&lt;/span&gt;
&lt;span class="no"&gt;Resolution&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="no"&gt;Donot&lt;/span&gt; &lt;span class="n"&gt;attempt&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;persist&lt;/span&gt; &lt;span class="n"&gt;documents&lt;/span&gt; &lt;span class="n"&gt;that&lt;/span&gt; &lt;span class="n"&gt;are&lt;/span&gt; &lt;span class="n"&gt;flagged&lt;/span&gt; &lt;span class="n"&gt;as&lt;/span&gt; &lt;span class="n"&gt;readonly&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;另外使用 only 后，如果直接读取没有加载的属性，将抛出异常&lt;code&gt;ActiveModel::MissingAttributeError: Missing attribute: 'not_load_attr’&lt;/code&gt;。在 Mongoid3 中返回 nil。&lt;/p&gt;

&lt;p&gt;下面是一些升级指导的链接&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://edgeguides.rubyonrails.org/upgrading_ruby_on_rails.html#upgrading-from-rails-3.2-to-rails-4.0" rel="nofollow" target="_blank" title=""&gt;http://edgeguides.rubyonrails.org/upgrading_ruby_on_rails.html#upgrading-from-rails-3.2-to-rails-4.0&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.oschina.net/translate/get-your-app-ready-for-rails-4" rel="nofollow" target="_blank" title=""&gt;http://www.oschina.net/translate/get-your-app-ready-for-rails-4&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ruby-china.org/topics/15579" title=""&gt;https://ruby-china.org/topics/15579&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.sitepoint.com/get-your-app-ready-for-rails-4/" rel="nofollow" target="_blank" title=""&gt;http://www.sitepoint.com/get-your-app-ready-for-rails-4/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;原文来自&lt;a href="http://jiangpeng.info/blogs/2014/08/26/tricks-on-upgrading-rails-from-3-2-to-4-0.html" rel="nofollow" target="_blank" title=""&gt;我的博客&lt;/a&gt;，不正确的地方欢迎大家交流。&lt;/p&gt;</description>
      <author>warmwind</author>
      <pubDate>Sat, 27 Sep 2014 17:53:33 +0800</pubDate>
      <link>https://ruby-china.org/topics/21748</link>
      <guid>https://ruby-china.org/topics/21748</guid>
    </item>
  </channel>
</rss>
