<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>martin (徐祥军（Martin）)</title>
    <link>https://ruby-china.org/martin</link>
    <description></description>
    <language>en-us</language>
    <item>
      <title> [上海]  QLEAR 招聘 Ruby 工程师 2 名 (20 - 35K) (5月3日 更新)</title>
      <description>&lt;h2 id="About QLEAR"&gt;About QLEAR&lt;/h2&gt;
&lt;p&gt;QLEAR is helping to create healthier, more efficient, and green buildings by allowing them to communicate with the people who live, work, and play in them. Come join a small team, passionate about environmental sustainability to help build an open, highly scalable platform.&lt;/p&gt;
&lt;h2 id="Backend Engineer (Ruby)"&gt;Backend Engineer (Ruby)&lt;/h2&gt;
&lt;p&gt;Location: Shanghai&lt;/p&gt;

&lt;p&gt;Stack: Ruby on Rails, Redis, MySQL, Docker/LXC, Git&lt;/p&gt;
&lt;h3 id="What will you do?"&gt;What will you do?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Write clean, tested, Ruby and Java code&lt;/li&gt;
&lt;li&gt;Architect, build, and deploy APIs for web and mobile clients&lt;/li&gt;
&lt;li&gt;Architect, build, and deploy APIs for integrating with external partners, as well as internal system communication&lt;/li&gt;
&lt;li&gt;Architect, build, and support systems for scheduling and data processing at scale&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="What are we looking for?"&gt;What are we looking for?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Able to design and build elegant, usable, and robust APIs&lt;/li&gt;
&lt;li&gt;Experience building systems for high volume transaction processing&lt;/li&gt;
&lt;li&gt;Deep understanding of messaging, scheduling, and queuing architectures&lt;/li&gt;
&lt;li&gt;Expert knowledge of Ruby, Java and familiarity with Linux, containerization, and cloud computing&lt;/li&gt;
&lt;li&gt;Embraces a DevOps philosophy, closely collaborating with QA and operations engineers throughout the full product&lt;/li&gt;
&lt;li&gt;Comfortable working in English. Our team has a variety of English and Chinese levels, being able and willing to communicate in either language is preferred&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="待遇"&gt;待遇&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;13 薪，&lt;del&gt;15-30K&lt;/del&gt; 20-35K（根据面试结果来确定），甚至更高 &lt;/li&gt;
&lt;li&gt;弹性工作时间&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="工作地址"&gt;工作地址&lt;/h2&gt;
&lt;p&gt;利西路 102 号，靠近延安西路和江苏路，长宁区&lt;/p&gt;
&lt;h2 id="联系方式"&gt;联系方式&lt;/h2&gt;
&lt;p&gt;请将简历和 github 地址发送至 careers@qlear.build，谢谢:)&lt;/p&gt;
&lt;h2 id="更新记录"&gt;更新记录&lt;/h2&gt;&lt;h3 id="5月3号"&gt;5 月 3 号&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;发现薪资没有竞争力，已将 15 起调整为 20 起&lt;/li&gt;
&lt;li&gt;另外公司融资已快结束，国外的同行投的，应该会有很不错的发展空间。&lt;/li&gt;
&lt;/ul&gt;</description>
      <author>martin</author>
      <pubDate>Thu, 20 Apr 2017 17:01:16 +0800</pubDate>
      <link>https://ruby-china.org/topics/32833</link>
      <guid>https://ruby-china.org/topics/32833</guid>
    </item>
    <item>
      <title>大家谨慎使用 DaoVoice 吧</title>
      <description>&lt;p&gt;我们在一个项目中采用过 DaoVoice，并且将部分客户的电子邮件同步过去了，不过让人很失望的是，客户 (包括我们自己的员工，内部邮箱) 收到了他们的广告邮件。&lt;/p&gt;

&lt;p&gt;真实让人感到震惊和羞愧。没啥事情，只是来吐槽下，顺便告诉大家谨慎点使用。&lt;/p&gt;</description>
      <author>martin</author>
      <pubDate>Wed, 27 Jul 2016 13:33:59 +0800</pubDate>
      <link>https://ruby-china.org/topics/30637</link>
      <guid>https://ruby-china.org/topics/30637</guid>
    </item>
    <item>
      <title>收到 oneapm 的书了，很惊喜，分享下。</title>
      <description>&lt;p&gt;之前看到这个帖子 &lt;a href="https://ruby-china.org/topics/27020" rel="nofollow" target="_blank"&gt;https://ruby-china.org/topics/27020&lt;/a&gt; 顺势进去投了个票，后来就忘记这个事情了，今天早上突然有个快递，拆开发现居然是我那天投票留得书，太意外了，太惊喜了。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/2015/57230bbf2e54d673aec8372e3e5d5f81.jpg" title="" alt=""&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/2015/3ec79c4643a39663aab0e1d3e6cac457.jpg" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/2015/3fb4330ae4ff35d8c9c268c27d289915.jpg" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/2015/3c3a7fc92c119711c1128c0ee72dd6fa.jpg" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;再次向 &lt;a href="/oneapm" class="user-mention" title="@oneapm"&gt;&lt;i&gt;@&lt;/i&gt;oneapm&lt;/a&gt; 表示感谢，谢谢！&lt;/p&gt;</description>
      <author>martin</author>
      <pubDate>Wed, 26 Aug 2015 11:29:28 +0800</pubDate>
      <link>https://ruby-china.org/topics/27086</link>
      <guid>https://ruby-china.org/topics/27086</guid>
    </item>
    <item>
      <title>Ruby 发展史</title>
      <description>&lt;p&gt;&lt;a href="http://metanest.jp/ruby-legends/" rel="nofollow" target="_blank"&gt;http://metanest.jp/ruby-legends/&lt;/a&gt;&lt;/p&gt;</description>
      <author>martin</author>
      <pubDate>Tue, 31 Mar 2015 10:32:49 +0800</pubDate>
      <link>https://ruby-china.org/topics/24926</link>
      <guid>https://ruby-china.org/topics/24926</guid>
    </item>
    <item>
      <title>转让一台 MacBook Pro</title>
      <description>&lt;p&gt;老款 A1278，11 年入手，13 年换了一台新的后就一直闲置在家，放在家占地方，所以想转让。外部有划痕，我本人使用电脑没那么小心:(  个人认为还比较实用，价格买的时候为 8K 多点，现在考虑在 &lt;del&gt;3700&lt;/del&gt; &lt;del&gt;3500&lt;/del&gt; 3300，有需要的可以联系我。&lt;/p&gt;

&lt;p&gt;只考虑上海地区的，怕麻烦，先验完货后再付费。&lt;/p&gt;

&lt;p&gt;系统被我升到 10.10 了&lt;/p&gt;

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

&lt;p&gt;联系方式：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Base64&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;decode64&lt;/span&gt; &lt;span class="s2"&gt;"TW9iaWxlOiAxODkxNzk1NzA1Mw=="&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;</description>
      <author>martin</author>
      <pubDate>Mon, 12 Jan 2015 21:24:53 +0800</pubDate>
      <link>https://ruby-china.org/topics/23692</link>
      <guid>https://ruby-china.org/topics/23692</guid>
    </item>
    <item>
      <title>拒绝自己拼凑查询条件</title>
      <description>&lt;h2 id="1. 场景"&gt;1. 场景&lt;/h2&gt;
&lt;p&gt;最近接手一个代码，流程同我们平时看到的一样：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;前段输入参数并提交&lt;/li&gt;
&lt;li&gt;controller 判断并转 model 处理&lt;/li&gt;
&lt;li&gt;model 查询返回结果&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;这样就导致每个 controller/model 充斥了不同的判断条件和查询的组装，如&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Booking&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;corp_id: &lt;/span&gt;&lt;span class="n"&gt;corp_id&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:member&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="ss"&gt;:coach&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="ss"&gt;:training_item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;coach_id: &lt;/span&gt;&lt;span class="n"&gt;coach_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;coach_id&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;present?&lt;/span&gt;

&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;member_id: &lt;/span&gt;&lt;span class="n"&gt;member_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;member_id&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;present?&lt;/span&gt;
&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;training_item_id: &lt;/span&gt;&lt;span class="n"&gt;training_item_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;training_item_id&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;present?&lt;/span&gt;
&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;train_status: &lt;/span&gt;&lt;span class="n"&gt;train_status&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;train_status&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;present?&lt;/span&gt;
&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"name like ?"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'%#{member_name}%'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;member_name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;present?&lt;/span&gt;

&lt;span class="o"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;太过于繁琐！&lt;/p&gt;
&lt;h2 id="2. 方案"&gt;2. 方案&lt;/h2&gt;
&lt;p&gt;于是考虑将中间的共性提取出来，做成一个单独的 concern。&lt;/p&gt;

&lt;p&gt;直接上代码，刚写的，还热乎呢  &lt;img title=":smile:" alt="😄" src="https://twemoji.ruby-china.com/2/svg/1f604.svg" class="twemoji"&gt;  加了几个条件，更多的条件慢慢加上&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;#encoding: utf-8&lt;/span&gt;

&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;ActiveRecordSupport&lt;/span&gt;
  &lt;span class="kp"&gt;extend&lt;/span&gt; &lt;span class="no"&gt;ActiveSupport&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Concern&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;filter&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;
      &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;respond_to?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:filter_mapping&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;filter_mapping&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&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;field&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;config&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;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;is_a?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Hash&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nb"&gt;method&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:method&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:type&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="n"&gt;default_value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:default&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
          &lt;span class="k"&gt;else&lt;/span&gt;
            &lt;span class="nb"&gt;method&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;
            &lt;span class="n"&gt;type&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="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_sym&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="n"&gt;default_value&lt;/span&gt;
          &lt;span class="k"&gt;next&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;nil?&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;blank?&lt;/span&gt;

          &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nb"&gt;method&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_sym&lt;/span&gt;
            &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="ss"&gt;:equal&lt;/span&gt;
              &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_s&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;=?"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="ss"&gt;:like&lt;/span&gt;
              &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_s&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; like ?"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"%&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;%"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="ss"&gt;:compare&lt;/span&gt;
              &lt;span class="n"&gt;op&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
              &lt;span class="k"&gt;next&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="sx"&gt;%w{= &amp;gt; &amp;lt; &amp;gt;= &amp;lt;=}&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;include?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;op&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
              &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_s&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;op&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; ?"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;length&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="ss"&gt;:between&lt;/span&gt;
              &lt;span class="n"&gt;value_begin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_s&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;_begin"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
              &lt;span class="n"&gt;value_end&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_s&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;_end"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

              &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="ss"&gt;:date&lt;/span&gt;
                &lt;span class="n"&gt;value_begin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value_begin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;beginning_of_day&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;value_begin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;present?&lt;/span&gt;
                &lt;span class="n"&gt;value_end&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value_end&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;end_of_day&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;value_end&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;present?&lt;/span&gt;
              &lt;span class="k"&gt;elsif&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="ss"&gt;:time&lt;/span&gt;
                &lt;span class="n"&gt;value_begin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value_begin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;beginning_of_day&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;value_begin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;present?&lt;/span&gt;
                &lt;span class="n"&gt;value_end&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value_end&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;end_of_day&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;value_end&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;present?&lt;/span&gt;
              &lt;span class="k"&gt;end&lt;/span&gt;

              &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_s&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &amp;gt;= ?"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value_begin&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;value_begin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;present?&lt;/span&gt;
              &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_s&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &amp;lt;= ?"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value_end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;value_end&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;present?&lt;/span&gt;
            &lt;span class="k"&gt;else&lt;/span&gt;
              &lt;span class="c1"&gt;# type code here&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;span class="n"&gt;result&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;h2 id="3 使用"&gt;3 使用&lt;/h2&gt;&lt;h2 id="3.1 等于和模糊查询"&gt;3.1 等于和模糊查询&lt;/h2&gt;
&lt;p&gt;在 model 定义如下的元数据&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;Account&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;
  &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;ActiveRecordSupport&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;filter_mapping&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="ss"&gt;account: :equal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="ss"&gt;account_name: :like&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="ss"&gt;status: :equal&lt;/span&gt;
      &lt;span class="p"&gt;}&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;ul&gt;
&lt;li&gt;account 账号，等于查询&lt;/li&gt;
&lt;li&gt;account_name 账号的中文名称，模糊 like 查询&lt;/li&gt;
&lt;li&gt;status 账号状态，等于查询&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;这样在 Controller 中直接如下操作&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;AccountsController&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ConsoleController&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;index&lt;/span&gt;
    &lt;span class="vi"&gt;@accounts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;page&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vi"&gt;@page&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="nf"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="3.2 日期区间比较"&gt;3.2 日期区间比较&lt;/h2&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;filter_mapping&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="ss"&gt;account: :equal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="ss"&gt;day: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;method: :between&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;type: :date&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&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;ul&gt;
&lt;li&gt;day 统计日期到天&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;前段页面支持选择时间段，格式：字段_begin 和 字段_end&lt;/p&gt;

&lt;p&gt;页面如下：&lt;/p&gt;
&lt;pre class="highlight erb"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"col-sm-2 m-b-xs"&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;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"day_begin"&lt;/span&gt; &lt;span class="na"&gt;placeholder=&lt;/span&gt;&lt;span class="s"&gt;"开始时间"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"input-sm datepicker"&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;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"col-sm-2 m-b-xs"&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;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"day_end"&lt;/span&gt; &lt;span class="na"&gt;placeholder=&lt;/span&gt;&lt;span class="s"&gt;"结束时间"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"input-sm datepicker"&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;ul&gt;
&lt;li&gt;日期除了到天，还支持到秒&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;filter_mapping&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="ss"&gt;request_time: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;method: :between&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="ss"&gt;type: :time&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&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;h2 id="3.3 简单的数据比对"&gt;3.3 简单的数据比对&lt;/h2&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;filter_mapping&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="ss"&gt;count: :compare&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&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;注意前段需要将比较字符放在第一位，如：&lt;/p&gt;
&lt;pre class="highlight erb"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"col-sm-2 m-b-xs"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;select&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"count"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;option&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;/option&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;option&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"=0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;等于0&lt;span class="nt"&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;option&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"&amp;gt;0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;大于0&lt;span class="nt"&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/select&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;h2 id="3.4 默认值配置"&gt;3.4 默认值配置&lt;/h2&gt;
&lt;p&gt;支持默认值，如查询默认是查询 大于 0 的内容&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;filter_mapping&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="ss"&gt;account: :equal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="ss"&gt;count: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;method: :compare&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;default: &lt;/span&gt;&lt;span class="s1"&gt;'&amp;gt;0'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;}&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;想了想，主要用到也就这几个条件了，有再加，一会整理下放到 github。&lt;/p&gt;</description>
      <author>martin</author>
      <pubDate>Tue, 28 Oct 2014 10:39:28 +0800</pubDate>
      <link>https://ruby-china.org/topics/22299</link>
      <guid>https://ruby-china.org/topics/22299</guid>
    </item>
    <item>
      <title>大家都在用谁家的短信通道？</title>
      <description>&lt;p&gt;RT, 稳定，可靠，能快速下发的，支持上行和下行的。推荐一两个，多谢了。&lt;/p&gt;</description>
      <author>martin</author>
      <pubDate>Mon, 28 Jul 2014 14:04:00 +0800</pubDate>
      <link>https://ruby-china.org/topics/20712</link>
      <guid>https://ruby-china.org/topics/20712</guid>
    </item>
    <item>
      <title>Ruby 2.1 In Detail</title>
      <description>&lt;p&gt;&lt;a href="http://globaldev.co.uk/2014/05/ruby-2-1-in-detail" rel="nofollow" target="_blank"&gt;http://globaldev.co.uk/2014/05/ruby-2-1-in-detail&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;New versioning policy&lt;/li&gt;
&lt;li&gt;Required keyword arguments&lt;/li&gt;
&lt;li&gt;String#freeze optimisation&lt;/li&gt;
&lt;li&gt;def returns the method name as a Symbol&lt;/li&gt;
&lt;li&gt;Rational and Complex literals&lt;/li&gt;
&lt;li&gt;Array/Enumerable #to_h&lt;/li&gt;
&lt;li&gt;Fine grained method cache&lt;/li&gt;
&lt;li&gt;Exception&lt;/li&gt;
&lt;li&gt;Generational Garbage Collection&lt;/li&gt;
&lt;li&gt;GC&lt;/li&gt;
&lt;li&gt;GC tuning environment variables&lt;/li&gt;
&lt;li&gt;ObjectSpace tools to track down memory leaks&lt;/li&gt;
&lt;li&gt;Refinements&lt;/li&gt;
&lt;li&gt;String#scrub&lt;/li&gt;
&lt;li&gt;Bignum/Rational performance improvements&lt;/li&gt;
&lt;li&gt;$SAFE level 4 removed&lt;/li&gt;
&lt;li&gt;clock_gettime&lt;/li&gt;
&lt;li&gt;RubyGems updated&lt;/li&gt;
&lt;li&gt;Deprecated Rake features removed&lt;/li&gt;
&lt;li&gt;RDoc template update&lt;/li&gt;
&lt;li&gt;Process title&lt;/li&gt;
&lt;li&gt;Frozen Symbols&lt;/li&gt;
&lt;li&gt;Fixed eval scope leak&lt;/li&gt;
&lt;li&gt;#untrusted? is now an alias of #tainted?&lt;/li&gt;
&lt;li&gt;return in lambda now always returns from lambda&lt;/li&gt;
&lt;li&gt;Get interface addresses&lt;/li&gt;
&lt;li&gt;Named capture support in StringScanner&lt;/li&gt;
&lt;li&gt;YAML.safe_load&lt;/li&gt;
&lt;li&gt;Resolv one-shot MDNS and LOC record support&lt;/li&gt;
&lt;li&gt;Improved Socket error messages&lt;/li&gt;
&lt;li&gt;Hash#shift much faster&lt;/li&gt;
&lt;li&gt;Queue, SizedQueue, and ConditionVariable performance improvements&lt;/li&gt;
&lt;li&gt;Timeout internal exception can’t be rescued&lt;/li&gt;
&lt;li&gt;Easier streaming responses with WEBrick&lt;/li&gt;
&lt;li&gt;Numeric#step&lt;/li&gt;
&lt;li&gt;Use IO _nonblock without raising exceptions&lt;/li&gt;
&lt;li&gt;IO ignores internal encoding if external encoding is ASCII-8BIT&lt;/li&gt;
&lt;li&gt;#include and #prepend now public&lt;/li&gt;
&lt;li&gt;Module/Class #singleton_class?&lt;/li&gt;
&lt;li&gt;Module#ancestors more consistent&lt;/li&gt;
&lt;li&gt;Object#singleton_method&lt;/li&gt;
&lt;li&gt;Method#original_name&lt;/li&gt;
&lt;li&gt;Mutex#owned?&lt;/li&gt;
&lt;li&gt;Hash#reject&lt;/li&gt;
&lt;li&gt;Vector#cross_product&lt;/li&gt;
&lt;li&gt;Fixnum/Bignum #bit_length&lt;/li&gt;
&lt;li&gt;pack/unpack Native Endian long long&lt;/li&gt;
&lt;li&gt;Dir glob returns composed characters&lt;/li&gt;
&lt;li&gt;Better type coercion for Numeric#quo&lt;/li&gt;
&lt;li&gt;Binding#local_variable_get/_set/_defined?&lt;/li&gt;
&lt;li&gt;CGI class methods now available from CGI::Util module&lt;/li&gt;
&lt;li&gt;Digest::Class.file passes arguments to initialiser&lt;/li&gt;
&lt;li&gt;Net::SMTP#rset&lt;/li&gt;
&lt;li&gt;open-uri supports repeated headers&lt;/li&gt;
&lt;li&gt;Write to files with Pathname&lt;/li&gt;
&lt;li&gt;Tempfile.create&lt;/li&gt;
&lt;li&gt;Rinda multicast support&lt;/li&gt;
&lt;li&gt;Easy setting of extra HTTP options for XMLRPC&lt;/li&gt;
&lt;li&gt;URI.encode_/decode_www_form updated to match WHATWG standard&lt;/li&gt;
&lt;li&gt;RbConfig::SIZEOF&lt;/li&gt;
&lt;li&gt;Can set facility with Syslog::Logger&lt;/li&gt;
&lt;li&gt;CSV.foreach with no block returns working enumerator&lt;/li&gt;
&lt;li&gt;OpenSSL bignum&lt;/li&gt;
&lt;li&gt;Enumerator.new size argument fixed to accept any callable object&lt;/li&gt;
&lt;li&gt;curses library removed&lt;/li&gt;
&lt;li&gt;TSort class methods&lt;/li&gt;
&lt;li&gt;TCP Fast Open&lt;/li&gt;
&lt;/ul&gt;</description>
      <author>martin</author>
      <pubDate>Fri, 09 May 2014 13:40:37 +0800</pubDate>
      <link>https://ruby-china.org/topics/19124</link>
      <guid>https://ruby-china.org/topics/19124</guid>
    </item>
    <item>
      <title>小说采集项目</title>
      <description>&lt;h2 id="序幕"&gt;序幕&lt;/h2&gt;
&lt;p&gt;看小说看多了，一直没有钟情一个网站，总是感觉众多不爽的地方，于是乎无聊的人脑袋一热，在国庆前的某一个晚上开始编码。&lt;/p&gt;

&lt;p&gt;国庆就扔在服务器上跑，很长时间之后发现有了千万的章节数据，很是欣喜，使用 scaffold 生成了几个页面供自己看小说，自娱自乐。&lt;/p&gt;

&lt;p&gt;不过最近想来这破玩意也没啥用，就想分享给各位想做类似的网站或者想抓取网页内容的看客，希望能给各位一点有用的帮助吧。&lt;/p&gt;
&lt;h2 id="期望"&gt;期望&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;希望能定时抓取不同小说站点的小说，&lt;/li&gt;
&lt;li&gt;并选择最好的最优质的内容输出给用户&lt;/li&gt;
&lt;li&gt;同时支持多种输出渠道&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="实现"&gt;实现&lt;/h2&gt;
&lt;p&gt;已经实现了 ranwen 整站抓取和更新（V1.1.0 版本）
  已经实现多源支持（master）
  已经实现规则配置抓取内容 (master)，如：目前起点网站列表抓取规则：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;rules&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;#书籍列表&lt;/span&gt;
    &lt;span class="ss"&gt;book: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="ss"&gt;list: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="ss"&gt;url: &lt;/span&gt;&lt;span class="s1"&gt;'http://all.qidian.com/book/bookstore.aspx?PageIndex=:page'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="ss"&gt;path: &lt;/span&gt;&lt;span class="s1"&gt;'div.twoleft'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="ss"&gt;item: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="ss"&gt;path: &lt;/span&gt;&lt;span class="s1"&gt;'div.sw2,div.sw1'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="ss"&gt;segments: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="ss"&gt;title: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="ss"&gt;path: &lt;/span&gt;&lt;span class="s1"&gt;'div.swb/span.swbt/a'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="ss"&gt;type: &lt;/span&gt;&lt;span class="s1"&gt;'href'&lt;/span&gt;
                    &lt;span class="p"&gt;},&lt;/span&gt;
                    &lt;span class="ss"&gt;last_chapter: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="ss"&gt;path: &lt;/span&gt;&lt;span class="s1"&gt;'div.swb/a.hui2'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="ss"&gt;type: &lt;/span&gt;&lt;span class="s1"&gt;'href'&lt;/span&gt;
                    &lt;span class="p"&gt;},&lt;/span&gt;
                    &lt;span class="ss"&gt;word_count: &lt;/span&gt;&lt;span class="s1"&gt;'div.swc'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="ss"&gt;author: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="ss"&gt;path: &lt;/span&gt;&lt;span class="s1"&gt;'div.swd/a'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="ss"&gt;type: &lt;/span&gt;&lt;span class="s1"&gt;'href'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="ss"&gt;save_url: &lt;/span&gt;&lt;span class="kp"&gt;false&lt;/span&gt;
                    &lt;span class="p"&gt;},&lt;/span&gt;
                    &lt;span class="ss"&gt;last_updated_at: &lt;/span&gt;&lt;span class="s1"&gt;'div.swe'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="ss"&gt;category_id: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="ss"&gt;path: &lt;/span&gt;&lt;span class="s1"&gt;'div.swa'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="ss"&gt;pattern: &lt;/span&gt;&lt;span class="s1"&gt;'SubCategoryId=(\d+)'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="ss"&gt;category: &lt;/span&gt;&lt;span class="s1"&gt;'regexp'&lt;/span&gt;
                    &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;

            &lt;span class="ss"&gt;paging: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="ss"&gt;path: &lt;/span&gt;&lt;span class="s1"&gt;'div.storelistbottom'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="ss"&gt;current_page: &lt;/span&gt;&lt;span class="s1"&gt;'a.f_s'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="ss"&gt;pages: &lt;/span&gt;&lt;span class="s1"&gt;'a.f_a'&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;

        &lt;span class="c1"&gt;#书籍明细，如图片，公告，评论等&lt;/span&gt;
        &lt;span class="ss"&gt;info: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="c1"&gt;#书籍章节列表&lt;/span&gt;
        &lt;span class="ss"&gt;chapter: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="c1"&gt;#书籍正文信息&lt;/span&gt;
        &lt;span class="ss"&gt;content: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="p"&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;h2 id="计划"&gt;计划&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;更多小说站点的专区&lt;/li&gt;
&lt;li&gt;友好的前段体验&lt;/li&gt;
&lt;li&gt;客户端支持&lt;/li&gt;
&lt;li&gt;单行本生成&lt;/li&gt;
&lt;li&gt;...&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="源头"&gt;源头&lt;/h2&gt;
&lt;p&gt;这里源是指小说提供的站点&lt;/p&gt;

&lt;p&gt;小说章节信息&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ranwen&lt;/li&gt;
&lt;li&gt;tieba （&lt;a href="/williamherry" class="user-mention" title="@williamherry"&gt;&lt;i&gt;@&lt;/i&gt;williamherry&lt;/a&gt;的建议）&lt;/li&gt;
&lt;li&gt;等待你的补充&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;小说基本信息  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;起点&lt;/li&gt;
&lt;li&gt;纵横&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="项目"&gt;项目&lt;/h2&gt;
&lt;p&gt;项目地址：&lt;a href="https://github.com/yuesmart/mori" rel="nofollow" target="_blank"&gt;https://github.com/yuesmart/mori&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;鸡蛋啥的随便扔 :)  对了，忘记说了，没有 test case，嘿嘿&lt;/p&gt;
&lt;h2 id="演示"&gt;演示&lt;/h2&gt;
&lt;p&gt;&lt;del&gt;演示地址：暂时去掉了&lt;/del&gt;&lt;/p&gt;

&lt;p&gt;&lt;del&gt;* 我不期望你推广，也不要常年蹲上面，服务器有压力，看完赶紧给我闪人 :)&lt;/del&gt;
&lt;del&gt;* 界面土那是一定的，不过是 scaffold 生成，千篇一律的 bootstrap 破玩意&lt;/del&gt;&lt;/p&gt;

&lt;p&gt;&lt;del&gt;演示中很多小说章节的上下级关系没跑，你可以尝试在右边的输入框中输入 &lt;strong&gt;星神&lt;/strong&gt; ，然后敲回车，选择 &lt;strong&gt;断晨风&lt;/strong&gt; 的那本&lt;/del&gt;&lt;/p&gt;
&lt;h2 id="开工"&gt;开工&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;如果你要自己折腾，自己 fork&lt;/li&gt;
&lt;li&gt;如果你要参加到这个项目中，告诉我下你的账号，我加你进来&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone git@github.com:yuesmart/mori.git
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="截图"&gt;截图&lt;/h2&gt;
&lt;p&gt;最后为了引诱那些小伙伴们，来点截图吧&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;首页&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src="https://raw.github.com/yuesmart/mori/master/doc/snip/Snip20131125_1.png" title="" alt="S1"&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;章节列表&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src="https://raw.github.com/yuesmart/mori/master/doc/snip/Snip20131125_2.png" title="" alt="S2"&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;正文&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src="https://raw.github.com/yuesmart/mori/master/doc/snip/Snip20131125_3.png" title="" alt="S3"&gt; &lt;/p&gt;

&lt;p&gt;打完收工，写文档比写代码累！&lt;/p&gt;</description>
      <author>martin</author>
      <pubDate>Mon, 25 Nov 2013 16:00:13 +0800</pubDate>
      <link>https://ruby-china.org/topics/15779</link>
      <guid>https://ruby-china.org/topics/15779</guid>
    </item>
    <item>
      <title>寻上海地区工作一枚</title>
      <description>&lt;p&gt;NOP&lt;/p&gt;</description>
      <author>martin</author>
      <pubDate>Wed, 23 Jan 2013 21:10:00 +0800</pubDate>
      <link>https://ruby-china.org/topics/8308</link>
      <guid>https://ruby-china.org/topics/8308</guid>
    </item>
  </channel>
</rss>
