<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>cinic (夏龙云)</title>
    <link>https://ruby-china.org/cinic</link>
    <description></description>
    <language>en-us</language>
    <item>
      <title>酷站是不是 bug 啊？</title>
      <description>&lt;p&gt;点酷站进去后发现有点不对，下面是用 firefox 打开的，发现一直在 loading 一个请求&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/2015/4469d0247c7187f7b126c4068fc0eddb.png" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;用 chrome 试了一下，可以打开，正常显示的，可点了一下 Esc 键后，就变成下面这样了
&lt;img src="https://l.ruby-china.com/photo/2015/7af482459aa869eae27786b501037798.png" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;是有 bug 吗？&lt;/p&gt;</description>
      <author>cinic</author>
      <pubDate>Thu, 04 Jun 2015 11:14:10 +0800</pubDate>
      <link>https://ruby-china.org/topics/25877</link>
      <guid>https://ruby-china.org/topics/25877</guid>
    </item>
    <item>
      <title>Mongoid 中的 callback 陷阱</title>
      <description>&lt;p&gt;在 save 一个实例时，返回了 false，但查看 errors 却是空的，也就是说 validate 都通过了，但却没有保存成功。于是调用了 save！方法，报错：&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;Callback&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;Calling&lt;/span&gt; &lt;span class="n"&gt;save!&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt; &lt;span class="n"&gt;resulted&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;callback&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;If&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;before&lt;/span&gt; &lt;span class="n"&gt;callback&lt;/span&gt; &lt;span class="n"&gt;returns&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt; &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="n"&gt;using&lt;/span&gt; &lt;span class="no"&gt;Document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create!&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Document&lt;/span&gt;&lt;span class="c1"&gt;#save!, or Documnet#update_attributes! this error will get raised since the document did not actually get saved.&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;Double&lt;/span&gt; &lt;span class="n"&gt;check&lt;/span&gt; &lt;span class="n"&gt;all&lt;/span&gt; &lt;span class="n"&gt;before&lt;/span&gt; &lt;span class="n"&gt;callbacks&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;make&lt;/span&gt; &lt;span class="n"&gt;sure&lt;/span&gt; &lt;span class="n"&gt;they&lt;/span&gt; &lt;span class="n"&gt;are&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;unintentionally&lt;/span&gt; &lt;span class="n"&gt;returning&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
    &lt;span class="nf"&gt;from&lt;/span&gt; &lt;span class="sr"&gt;/Users/&lt;/span&gt;&lt;span class="n"&gt;cinic&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rvm&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;gems&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;ruby&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;2.1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;gems&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;mongoid&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;4.0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;mongoid&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;persistable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;93&lt;/span&gt;&lt;span class="ss"&gt;:in&lt;/span&gt; &lt;span class="sb"&gt;`fail_due_to_callback!'
    from /Users/cinic/.rvm/gems/ruby-2.1.4/gems/mongoid-4.0.0/lib/mongoid/persistable/savable.rb:46:in `&lt;/span&gt;&lt;span class="n"&gt;save!&lt;/span&gt;&lt;span class="s1"&gt;'
    from (irb):6
    from /Users/cinic/.rvm/gems/ruby-2.1.4/gems/railties-4.1.7/lib/rails/commands/console.rb:90:in `start'&lt;/span&gt;
    &lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="sr"&gt;/Users/&lt;/span&gt;&lt;span class="n"&gt;cinic&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rvm&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;gems&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;ruby&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;2.1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;gems&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;railties&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;4.1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;rails&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;commands&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="ss"&gt;:in&lt;/span&gt; &lt;span class="sb"&gt;`start'
    from /Users/cinic/.rvm/gems/ruby-2.1.4/gems/railties-4.1.7/lib/rails/commands/commands_tasks.rb:69:in `&lt;/span&gt;&lt;span class="n"&gt;console&lt;/span&gt;&lt;span class="s1"&gt;'
    from /Users/cinic/.rvm/gems/ruby-2.1.4/gems/railties-4.1.7/lib/rails/commands/commands_tasks.rb:40:in `run_command!'&lt;/span&gt;
    &lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="sr"&gt;/Users/&lt;/span&gt;&lt;span class="n"&gt;cinic&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rvm&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;gems&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;ruby&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;2.1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;gems&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;railties&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;4.1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;rails&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;commands&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;17&lt;/span&gt;&lt;span class="ss"&gt;:in&lt;/span&gt; &lt;span class="sb"&gt;`&amp;lt;top (required)&amp;gt;'
    from bin/rails:4:in `&lt;/span&gt;&lt;span class="nb"&gt;require&lt;/span&gt;&lt;span class="s1"&gt;'
    from bin/rails:4:in `&amp;lt;main&amp;gt;'&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;根据报错信息，又去类里查看了所以的 callback 方法，其实只有一个 before_save：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;is_member&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;point&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;就是检查某个值大于 0 时，将另一个值设为 true，否则为 false。问题就在这里，因为有可能是返回的 false，所以导致这个 callback 最后的返回值也是 false，最后解决是在这个方法最后加上 return true。有没有碰到过这样问题的，这算是个 Bug 吗？&lt;/p&gt;

&lt;p&gt;Mongoid 的文档中有这样说：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Using&lt;/span&gt; &lt;span class="n"&gt;callbacks&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;domain&lt;/span&gt; &lt;span class="n"&gt;logic&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;bad&lt;/span&gt; &lt;span class="n"&gt;design&lt;/span&gt; &lt;span class="n"&gt;practice&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;can&lt;/span&gt; &lt;span class="n"&gt;lead&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;unexpected&lt;/span&gt; &lt;span class="n"&gt;errors&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;hard&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;debug&lt;/span&gt; &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="n"&gt;callbacks&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;chain&lt;/span&gt; &lt;span class="n"&gt;halt&lt;/span&gt; &lt;span class="n"&gt;execution&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="no"&gt;It&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;our&lt;/span&gt; &lt;span class="n"&gt;recommendation&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;only&lt;/span&gt; &lt;span class="n"&gt;use&lt;/span&gt; &lt;span class="n"&gt;them&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;cross&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;cutting&lt;/span&gt; &lt;span class="n"&gt;concerns&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;like&lt;/span&gt; &lt;span class="n"&gt;queueing&lt;/span&gt; &lt;span class="n"&gt;up&lt;/span&gt; &lt;span class="n"&gt;background&lt;/span&gt; &lt;span class="n"&gt;jobs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;是不是不应该这么用 callback 呢？&lt;/p&gt;</description>
      <author>cinic</author>
      <pubDate>Mon, 04 May 2015 15:45:29 +0800</pubDate>
      <link>https://ruby-china.org/topics/25421</link>
      <guid>https://ruby-china.org/topics/25421</guid>
    </item>
  </channel>
</rss>
