<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>kikyous</title>
    <link>https://ruby-china.org/kikyous</link>
    <description></description>
    <language>en-us</language>
    <item>
      <title>Rails 8.0: No PaaS Required</title>
      <description>&lt;p&gt;&lt;a href="https://rubyonrails.org/2024/11/7/rails-8-no-paas-required" rel="nofollow" target="_blank"&gt;https://rubyonrails.org/2024/11/7/rails-8-no-paas-required&lt;/a&gt;&lt;/p&gt;</description>
      <author>kikyous</author>
      <pubDate>Fri, 08 Nov 2024 10:10:33 +0800</pubDate>
      <link>https://ruby-china.org/topics/43937</link>
      <guid>https://ruby-china.org/topics/43937</guid>
    </item>
    <item>
      <title>Ruby 3.2 YJIT, malloctrim, jemalloc 性能测试</title>
      <description>&lt;p&gt;测试脚本是个修改版的查找最大子串的代码：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"./file.txt"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;find_common_sub_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;threshold&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;size&lt;/span&gt;
    &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;size&lt;/span&gt;

    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

    &lt;span class="c1"&gt;# Create DP table&lt;/span&gt;
    &lt;span class="n"&gt;dp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="no"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&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="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each_char&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each_with_index&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;s_char&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;s_index&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s_index&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
        &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each_char&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each_with_index&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;t_char&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;t_index&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
            &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;t_index&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;s_char&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;t_char&lt;/span&gt;
                &lt;span class="n"&gt;dp&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dp&lt;/span&gt;&lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dp&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;threshold&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&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;push&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;dp&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;j&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;else&lt;/span&gt;
                &lt;span class="n"&gt;dp&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;dp&lt;/span&gt;&lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;threshold&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;push&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dp&lt;/span&gt;&lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&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;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;find_common_sub_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content&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="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;content&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="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;测试跑在 container 里，使用 earthly 运行：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;VERSION 0.6

ruby32:
    FROM ruby:3.2-alpine
    ENV TIME="time result cmd: %C  real: %es  user: %Us  sys: %Ss  memory: %MKB  cpu: %P"
    COPY . .
    RUN --no-cache sh -c '/usr/bin/time ruby --yjit diff.rb'
    RUN --no-cache sh -c '/usr/bin/time ruby  diff.rb'

fullstaqruby32-jemalloc:
    FROM quay.io/evl.ms/fullstaq-ruby:3.2.0-jemalloc
    RUN apt-get update -yqq &amp;amp;&amp;amp; apt-get install -yqq --no-install-recommends time
    ENV TIME="time result\ncmd:%C\nreal %es\nuser %Us \nsys  %Ss \nmemory:%MKB \ncpu %P"
    COPY . .
    RUN --no-cache bash -c '/usr/bin/time ruby --yjit diff.rb'
    RUN --no-cache bash -c '/usr/bin/time ruby diff.rb'

fullstaqruby32-malloctrim:
    FROM quay.io/evl.ms/fullstaq-ruby:3.2.0-malloctrim-stretch
    RUN apt-get update -yqq &amp;amp;&amp;amp; apt-get install -yqq --no-install-recommends time
    ENV TIME="time result\ncmd:%C\nreal %es\nuser %Us \nsys  %Ss \nmemory:%MKB \ncpu %P"
    COPY . .
    RUN --no-cache bash -c '/usr/bin/time ruby --yjit diff.rb'
    RUN --no-cache bash -c '/usr/bin/time ruby diff.rb'
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="输出:"&gt;输出：&lt;/h2&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt; 1. Init 🚀
————————————————————————————————————————————————————————————————————————————————

           buildkitd | Found buildkit daemon as docker container (earthly-buildkitd)

 2. Build 🔧
————————————————————————————————————————————————————————————————————————————————

     ruby:3.2-alpine | --&amp;gt; Load metadata linux/amd64
q/e/fullstaq-ruby:3.2.0-jemalloc | --&amp;gt; Load metadata linux/amd64
q/e/fullstaq-ruby:3.2.0-malloctrim-stretch | --&amp;gt; Load metadata linux/amd64
+fullstaqruby32-jemalloc | --&amp;gt; FROM quay.io/evl.ms/fullstaq-ruby:3.2.0-jemalloc
             context | --&amp;gt; local context .
+fullstaqruby32-jemalloc | [          ]   0% resolve quay.io/evl.ms/fullstaq-ruby:3.2.0-jemalloc@sha256:d34dccb3cd5109ba13a4de9bc4be8d3ffc6b458d3b9[██████████] 100% resolve quay.io/evl.ms/fullstaq-ruby:3.2.0-jemalloc@sha256:d34dccb3cd5109ba13a4de9bc4be8d3ffc6b458d3b9c12abde6e4d39de7363c8
+fullstaqruby32-malloctrim | --&amp;gt; FROM quay.io/evl.ms/fullstaq-ruby:3.2.0-malloctrim-stretch
+fullstaqruby32-malloctrim | [          ]   0% resolve quay.io/evl.ms/fullstaq-ruby:3.2.0-malloctrim-stretch@sha256:0280d75ef0a524d180a3973224302cf5a[██████████] 100% resolve quay.io/evl.ms/fullstaq-ruby:3.2.0-malloctrim-stretch@sha256:0280d75ef0a524d180a3973224302cf5a1a9ae3b49032e7f4da4bb90bf11ad0f
             +ruby32 | --&amp;gt; FROM ruby:3.2-alpine
             +ruby32 | [          ]   0% resolve docker.io/library/ruby:3.2-alpine@sha256:a3130ddd747ae03e2a5ccc8b200840b5dc2d6804a021fdf6a0127[██████████] 100% resolve docker.io/library/ruby:3.2-alpine@sha256:a3130ddd747ae03e2a5ccc8b200840b5dc2d6804a021fdf6a012777c0d3f7a57
             context | [          ]   0% transferring .:
             context | [██████████] 100% transferring .:
             +ruby32 | *cached* --&amp;gt; COPY . .
+fullstaqruby32-jemalloc | *cached* --&amp;gt; RUN apt-get update -yqq &amp;amp;&amp;amp; apt-get install -yqq --no-install-recommends time
+fullstaqruby32-jemalloc | *cached* --&amp;gt; COPY . .
             +ruby32 | --&amp;gt; RUN --no-cache sh -c '/usr/bin/time ruby --yjit diff.rb'
+fullstaqruby32-malloctrim | *cached* --&amp;gt; RUN apt-get update -yqq &amp;amp;&amp;amp; apt-get install -yqq --no-install-recommends time
+fullstaqruby32-malloctrim | *cached* --&amp;gt; COPY . .
             ongoing | +ruby32 (17 seconds ago)
             +ruby32 | [[10000, 10000, 10000]]
             +ruby32 | time result cmd: ruby --yjit diff.rb  real: 18.48s  user: 18.40s  sys: 0.06s  memory: 92528KB  cpu: 99%
+fullstaqruby32-jemalloc | --&amp;gt; RUN --no-cache bash -c '/usr/bin/time ruby --yjit diff.rb'
             ongoing | +fullstaqruby32-jemalloc (17 seconds ago)
+fullstaqruby32-jemalloc | [[10000, 10000, 10000]]
+fullstaqruby32-jemalloc | time result
+fullstaqruby32-jemalloc | cmd:ruby --yjit diff.rb
+fullstaqruby32-jemalloc | real 17.25s
+fullstaqruby32-jemalloc | user 17.13s 
+fullstaqruby32-jemalloc | sys  0.10s 
+fullstaqruby32-jemalloc | memory:32456KB 
+fullstaqruby32-jemalloc | cpu 99%
+fullstaqruby32-malloctrim | --&amp;gt; RUN --no-cache bash -c '/usr/bin/time ruby --yjit diff.rb'
             ongoing | +fullstaqruby32-malloctrim (17 seconds ago)
+fullstaqruby32-malloctrim | [[10000, 10000, 10000]]
+fullstaqruby32-malloctrim | time result
+fullstaqruby32-malloctrim | cmd:ruby --yjit diff.rb
+fullstaqruby32-malloctrim | real 18.31s
+fullstaqruby32-malloctrim | user 18.24s 

+fullstaqruby32-malloctrim | sys  0.04s 
+fullstaqruby32-malloctrim | memory:23692KB 
+fullstaqruby32-malloctrim | cpu 99%
             +ruby32 | --&amp;gt; RUN --no-cache sh -c '/usr/bin/time ruby diff.rb'
             ongoing | +ruby32 (32 seconds ago)
             +ruby32 | [[10000, 10000, 10000]]
             +ruby32 | time result cmd: ruby diff.rb  real: 34.22s  user: 34.07s  sys: 0.14s  memory: 90000KB  cpu: 99%
+fullstaqruby32-jemalloc | --&amp;gt; RUN --no-cache bash -c '/usr/bin/time ruby diff.rb'
             ongoing | +fullstaqruby32-jemalloc (32 seconds ago)
+fullstaqruby32-jemalloc | [[10000, 10000, 10000]]
+fullstaqruby32-jemalloc | time result
+fullstaqruby32-jemalloc | cmd:ruby diff.rb
+fullstaqruby32-jemalloc | real 32.69s
+fullstaqruby32-jemalloc | user 32.61s 
+fullstaqruby32-jemalloc | sys  0.06s 
+fullstaqruby32-jemalloc | memory:32068KB 
+fullstaqruby32-jemalloc | cpu 99%
+fullstaqruby32-malloctrim | --&amp;gt; RUN --no-cache bash -c '/usr/bin/time ruby diff.rb'
             ongoing | +fullstaqruby32-malloctrim (32 seconds ago)
+fullstaqruby32-malloctrim | [[10000, 10000, 10000]]
+fullstaqruby32-malloctrim | time result
+fullstaqruby32-malloctrim | cmd:ruby diff.rb
+fullstaqruby32-malloctrim | real 33.97s
+fullstaqruby32-malloctrim | user 33.88s 
+fullstaqruby32-malloctrim | sys  0.09s 
+fullstaqruby32-malloctrim | memory:23080KB 
+fullstaqruby32-malloctrim | cpu 99%
              output | --&amp;gt; exporting outputs
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="结果"&gt;结果&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;跑了三次&lt;/p&gt;
&lt;/blockquote&gt;
&lt;table class="table table-bordered table-striped"&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;th&gt;version&lt;/th&gt;
&lt;th&gt;time&lt;/th&gt;
&lt;th&gt;memory&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ruby3.2&lt;/td&gt;
&lt;td&gt;34.98s,34.10s,34.22s&lt;/td&gt;
&lt;td&gt;89568KB,89584KB,90000KB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ruby3.2 --yjit&lt;/td&gt;
&lt;td&gt;19.83s,17.96s,18.48s&lt;/td&gt;
&lt;td&gt;92720KB,93280KB,92528KB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ruby3.2-malloctrim&lt;/td&gt;
&lt;td&gt;31.91s,33.60s,33.97s&lt;/td&gt;
&lt;td&gt;23240KB,23228KB,23080KB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ruby3.2-malloctrim --yjit&lt;/td&gt;
&lt;td&gt;18.89s,18.27s,18.31s&lt;/td&gt;
&lt;td&gt;23840KB,23736KB,23692KB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ruby3.2-jemalloc&lt;/td&gt;
&lt;td&gt;32.17s,32.71s,32.69s&lt;/td&gt;
&lt;td&gt;31824KB,32036KB,32068KB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ruby3.2-jemalloc --yjit&lt;/td&gt;
&lt;td&gt;16.66s,17.10s,17.25s&lt;/td&gt;
&lt;td&gt;32524KB,32424KB,32456KB&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;看的出来在此场景下 yjit 有超过 40% 的性能提升，jemalloc 和 malloctrim 对内存占用的优化很明显，甚至 malloctrim 的内存是最低的&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <author>kikyous</author>
      <pubDate>Thu, 05 Jan 2023 23:48:52 +0800</pubDate>
      <link>https://ruby-china.org/topics/42823</link>
      <guid>https://ruby-china.org/topics/42823</guid>
    </item>
    <item>
      <title>发现一个分页组件的 bug</title>
      <description>&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/2018/684b8b95-5d6f-488e-84c7-cb3f1fb29e52.png!large" title="" alt=""&gt;&lt;/p&gt;</description>
      <author>kikyous</author>
      <pubDate>Thu, 19 Jul 2018 13:51:33 +0800</pubDate>
      <link>https://ruby-china.org/topics/37191</link>
      <guid>https://ruby-china.org/topics/37191</guid>
    </item>
    <item>
      <title>Rails routing and namespaced models</title>
      <description>&lt;p&gt;在一个比较复杂的 rails 程序里，如果你使用 namespace 来进行模块化：&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;Admin::Company&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationRecord&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Admin::Custom&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationRecord&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;namespace&lt;/span&gt; &lt;span class="ss"&gt;:admin&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;resources&lt;/span&gt; &lt;span class="ss"&gt;:companies&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;resources&lt;/span&gt; &lt;span class="ss"&gt;:customs&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;在 form_for 时就会遇到麻烦&lt;/p&gt;
&lt;pre class="highlight erb"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="n"&gt;form_for&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="vi"&gt;@company&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="vi"&gt;@custom&lt;/span&gt;&lt;span class="p"&gt;])&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;f&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;&amp;lt;%&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这样 rails 会去找一个不存在的路由然后报错：
&lt;code&gt;undefined method admin_company_admin_customs_path&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;这样也会报错&lt;/p&gt;
&lt;pre class="highlight erb"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="n"&gt;form_for&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="ss"&gt;:admin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="vi"&gt;@company&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="vi"&gt;@custom&lt;/span&gt;&lt;span class="p"&gt;])&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;f&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;&amp;lt;%&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;undefined method admin_admin_company_admin_customs_path&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;我之前的解决方法都是给 form_for 传入 url 参数，手动指定 path，但是这样又要判断是 new 还是 edit&lt;/p&gt;

&lt;p&gt;今天终于找到了解决方法
在 admin.rb 里定义 &lt;code&gt;use_relative_model_naming?&lt;/code&gt;&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Admin&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use_relative_model_naming?&lt;/span&gt;
    &lt;span class="kp"&gt;true&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="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="n"&gt;form_for&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="ss"&gt;:admin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="vi"&gt;@company&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="vi"&gt;@custom&lt;/span&gt;&lt;span class="p"&gt;])&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;f&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;&amp;lt;%&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;一切又回归优雅了&lt;img title=":grinning:" alt="😀" src="https://twemoji.ruby-china.com/2/svg/1f600.svg" class="twemoji"&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://coderwall.com/p/heed_q/rails-routing-and-namespaced-models" rel="nofollow" target="_blank"&gt;https://coderwall.com/p/heed_q/rails-routing-and-namespaced-models&lt;/a&gt;&lt;/p&gt;</description>
      <author>kikyous</author>
      <pubDate>Tue, 01 Aug 2017 10:15:11 +0800</pubDate>
      <link>https://ruby-china.org/topics/33685</link>
      <guid>https://ruby-china.org/topics/33685</guid>
    </item>
    <item>
      <title>Hello Sidekiq 5.0</title>
      <description>&lt;p&gt;&lt;a href="http://www.mikeperham.com/2017/04/25/hello-sidekiq-5.0/" rel="nofollow" target="_blank"&gt;http://www.mikeperham.com/2017/04/25/hello-sidekiq-5.0/&lt;/a&gt;&lt;/p&gt;</description>
      <author>kikyous</author>
      <pubDate>Thu, 27 Apr 2017 11:30:59 +0800</pubDate>
      <link>https://ruby-china.org/topics/32884</link>
      <guid>https://ruby-china.org/topics/32884</guid>
    </item>
    <item>
      <title>sprockets-vue 0.1 发布，已经有 49 个 star ❤️</title>
      <description>&lt;p&gt;&lt;a href="https://github.com/kikyous/sprockets-vue" rel="nofollow" target="_blank"&gt;https://github.com/kikyous/sprockets-vue&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;简单的来说这个 gem 就是把.vue 文件转换成 js 对象（不需要 vueloader，webpack 等），让你享受.vue 单文件组件的同时使用 rails 原生一套东西，并保持现有的部署方法&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="举个栗子"&gt;举个栗子&lt;/h2&gt;
&lt;p&gt;#app.vue&lt;/p&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"coffee"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="na"&gt;users&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="na"&gt;methods&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;v-for=&lt;/span&gt;&lt;span class="s"&gt;"m in users"&lt;/span&gt; &lt;span class="na"&gt;:m=&lt;/span&gt;&lt;span class="s"&gt;'m'&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;style &lt;/span&gt;&lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"scss"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;现在你可以在 js 或者 coffee 中直接引入这个组件：&lt;/p&gt;

&lt;p&gt;#application.coffee&lt;/p&gt;
&lt;pre class="highlight coffeescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;#= require app&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;现在你就可以通过全局变量&lt;code&gt;VComponents&lt;/code&gt;来访问 app 了&lt;/p&gt;
&lt;pre class="highlight coffeescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;#= require app&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Vue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="na"&gt;el&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'#main'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;components&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;'app'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;VComponents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;app&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;p&gt;0.1 是比较大的更新：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;script 中使用&lt;code&gt;module.exports={}&lt;/code&gt;而不是&lt;code&gt;vm={}&lt;/code&gt;，尽量和 vueloader 保持一直&lt;/li&gt;
&lt;li&gt;使用&lt;code&gt;VComponents&lt;/code&gt;而不是&lt;code&gt;VCompents&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;script 支持原生 js&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;感谢 &lt;a href="https://github.com/dts" rel="nofollow" target="_blank"&gt;https://github.com/dts&lt;/a&gt; 的贡献&lt;/p&gt;</description>
      <author>kikyous</author>
      <pubDate>Thu, 09 Feb 2017 09:19:17 +0800</pubDate>
      <link>https://ruby-china.org/topics/32279</link>
      <guid>https://ruby-china.org/topics/32279</guid>
    </item>
    <item>
      <title>Is Ruby dead? Hell no! - Analyzing RubyGems stats for 2016</title>
      <description>&lt;blockquote&gt;
&lt;p&gt;我就搬几张图过来 &lt;a href="https://infinum.co/the-capsized-eight/analyzing-rubygems-stats-v2016" rel="nofollow" target="_blank"&gt;https://infinum.co/the-capsized-eight/analyzing-rubygems-stats-v2016&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="Gem creation continues to fall"&gt;Gem creation continues to fall&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://ww2.sinaimg.cn/large/006y8lValy1fbz6ubhfsoj30qo0dwwer.jpg" title="" alt=""&gt;&lt;/p&gt;
&lt;h2 id="Gem releases going down"&gt;Gem releases going down&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://ww2.sinaimg.cn/large/006y8lValy1fbz6uxwr2gj30qo0dwq39.jpg" title="" alt=""&gt;&lt;/p&gt;
&lt;h2 id="Rails downloads are still increasing"&gt;Rails downloads are still increasing&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://ww2.sinaimg.cn/large/006y8lValy1fbz6v9ord5j30qo0d23ym.jpg" title="" alt=""&gt;&lt;/p&gt;
&lt;h2 id="Application Servers"&gt;Application Servers&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://ww1.sinaimg.cn/large/006y8lValy1fbz6vt9f53j30qo0fkaah.jpg" title="" alt=""&gt;&lt;/p&gt;
&lt;h2 id="RSpec - The New King of Testing"&gt;RSpec - The New King of Testing&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://ww2.sinaimg.cn/large/006y8lValy1fbz6wf8jsnj30qo0eqwep.jpg" title="" alt=""&gt;&lt;/p&gt;</description>
      <author>kikyous</author>
      <pubDate>Sun, 22 Jan 2017 10:19:50 +0800</pubDate>
      <link>https://ruby-china.org/topics/32191</link>
      <guid>https://ruby-china.org/topics/32191</guid>
    </item>
    <item>
      <title>被我遗忘的 Hash#dig</title>
      <description>&lt;p&gt;为了在 value 处取得 params[:q][:title_cont]&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'q[title_or_key_cont]'&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"text"&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'&amp;lt;%= params[:q][:title_cont] %&amp;gt;'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这样在 params[:q] 为 nil 时会报错，
曾经一直这么写：&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="ss"&gt;:q&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="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:q&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="ss"&gt;:title_cont&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;还可以用 try 改进：&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="ss"&gt;:q&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;try&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:[]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:name_cont&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;现在有更厉害的方法了：ruby 2.3 中引入的 Hash#dig&lt;/p&gt;

&lt;p&gt;于是只需要：&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;dig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:q&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:title_cont&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img title=":clap:" alt="👏" src="https://twemoji.ruby-china.com/2/svg/1f44f.svg" class="twemoji"&gt; &lt;/p&gt;</description>
      <author>kikyous</author>
      <pubDate>Mon, 09 Jan 2017 15:15:13 +0800</pubDate>
      <link>https://ruby-china.org/topics/32080</link>
      <guid>https://ruby-china.org/topics/32080</guid>
    </item>
    <item>
      <title>[ANN] Rails 5.0.1 has been released!</title>
      <description>&lt;p&gt;&lt;a href="http://weblog.rubyonrails.org/2016/12/21/Rails-5-0-1-has-been-released/" rel="nofollow" target="_blank"&gt;http://weblog.rubyonrails.org/2016/12/21/Rails-5-0-1-has-been-released/&lt;/a&gt;&lt;/p&gt;</description>
      <author>kikyous</author>
      <pubDate>Thu, 22 Dec 2016 11:05:05 +0800</pubDate>
      <link>https://ruby-china.org/topics/31971</link>
      <guid>https://ruby-china.org/topics/31971</guid>
    </item>
    <item>
      <title>sprockets-vue 把 .vue 文件和 Rails Asset Pipeline 结合起来</title>
      <description>&lt;p&gt;&lt;a href="https://github.com/kikyous/sprockets-vue" rel="nofollow" target="_blank"&gt;https://github.com/kikyous/sprockets-vue&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;可以在 rails 项目中直接使用.vue 文件，不用 vue-loader, webpack 什么的，直接和 Rails Asset Pipeline 结合&lt;/p&gt;
&lt;h2 id="单独.vue 文件的优势"&gt;单独.vue 文件的优势&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;方便管理&lt;/li&gt;
&lt;li&gt;template 放在独立的位置，不用写在字符串里，可以利用现有的编辑器语法高亮和智能缩进&lt;/li&gt;
&lt;li&gt;组件包含自己的样式&lt;/li&gt;
&lt;li&gt;...&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="sprockets-vue"&gt;sprockets-vue&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;sprockets-vue 支持全部 template, script, style 标签（不支持 scoped）&lt;/li&gt;
&lt;li&gt;在 js 或 vue 文件中 require .vue 文件：template, script 编译出的对象存储在&lt;code&gt;VCompents[filename]&lt;/code&gt;里面&lt;/li&gt;
&lt;li&gt;在 css 文件中 require .vue 文件：style 标签里的内容被处理后会添加在相应的位置（可以用 require_tree 包含所有的.vue 文件样式）&lt;/li&gt;
&lt;li&gt;script 暂时只支持 coffee&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="示例"&gt;示例&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;index.vue&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;//= require compents/card
&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"coffee"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;search&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;
    &lt;span class="nx"&gt;members&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="nx"&gt;components&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;card&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;VCompents&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;compents/card&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="nx"&gt;methods&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;search&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;template&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;"container"&lt;/span&gt;&lt;span class="nt"&gt;&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;'search icon-input'&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"search-icon glyphicon glyphicon-search"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"form-control"&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;v-model=&lt;/span&gt;&lt;span class="s"&gt;'search'&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;user1=&lt;/span&gt;&lt;span class="s"&gt;'clear'&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"clear-icon glyphicon glyphicon-remove"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/span&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;card&lt;/span&gt; &lt;span class="na"&gt;v-for=&lt;/span&gt;&lt;span class="s"&gt;"m in members"&lt;/span&gt; &lt;span class="na"&gt;:m=&lt;/span&gt;&lt;span class="s"&gt;'m'&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/card&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;/template&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;style &lt;/span&gt;&lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"scss"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s1"&gt;"bootstrap-sprockets"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s1"&gt;"bootstrap/variables"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s1"&gt;"bootstrap/mixins"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="nt"&gt;Reset&lt;/span&gt; &lt;span class="nt"&gt;and&lt;/span&gt; &lt;span class="nt"&gt;dependencies&lt;/span&gt;
  &lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s1"&gt;"bootstrap/normalize"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s1"&gt;"bootstrap/glyphicons"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="nt"&gt;Core&lt;/span&gt; &lt;span class="nt"&gt;CSS&lt;/span&gt;
  &lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s1"&gt;"bootstrap/scaffolding"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s1"&gt;"bootstrap/code"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s1"&gt;"bootstrap/forms"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s1"&gt;"bootstrap/media"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s1"&gt;"bootstrap/list-group"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s1"&gt;"bootstrap/panels"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s1"&gt;"bootstrap/utilities"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;application.coffee&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="highlight coffeescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;#= require index&lt;/span&gt;

&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Vue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="na"&gt;el&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'#search'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;components&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;'index'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;VCompents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;index&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;&lt;strong&gt;application.scss&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="c1"&gt;//=require index&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;</description>
      <author>kikyous</author>
      <pubDate>Tue, 25 Oct 2016 18:01:56 +0800</pubDate>
      <link>https://ruby-china.org/topics/31435</link>
      <guid>https://ruby-china.org/topics/31435</guid>
    </item>
    <item>
      <title>记一次 Redis 实战，实现答题系统</title>
      <description>&lt;p&gt;要做一个微信公众号答题系统，有一个题库，里面的题目分为 3 个难度等级，用户每次答题都是从每个等级随机选择一题，共三道题，答对的题不再出现。&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;Topic&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationRecord&lt;/span&gt;
  &lt;span class="n"&gt;enum&lt;/span&gt; &lt;span class="ss"&gt;level: &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="ss"&gt;:one&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:two&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:three&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;p&gt;随机选择题目想到了两种 sql 方案，一种是&lt;code&gt;order by rand()&lt;/code&gt;, 一种是取得每个难度的 count，然后&lt;code&gt;limit(1..count).first&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;而且要去掉已经答过的题目，需要建立新表记录答过的题目，再用复杂的子查询，如果题目规模很大，或者未来增加题目难度等级可能会导致性能非常的差！&lt;/p&gt;

&lt;p&gt;这时候就考虑使用 redis 来解决问题。&lt;/p&gt;
&lt;h2 id="首先需要在 redis 中为每个等级的题目维护一个 id 列表，可以选用 set。"&gt;首先需要在 redis 中为每个等级的题目维护一个 id 列表，可以选用 set。&lt;/h2&gt;&lt;table class="table table-bordered table-striped"&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;th&gt;Key&lt;/th&gt;
&lt;th&gt;Members&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;level_one_topic_set&lt;/td&gt;
&lt;td&gt;[1, 2, 3,  ...]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;level_two_topic_set&lt;/td&gt;
&lt;td&gt;[111, 112, 113, ...]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;level_three_topic_set&lt;/td&gt;
&lt;td&gt;[1111, 1112, 1113, ...]&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;这没什么难度，使用 active_record callback 就行，我把他做成了一个 gem Rediscord&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;Topic&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationRecord&lt;/span&gt;
  &lt;span class="n"&gt;enum&lt;/span&gt; &lt;span class="ss"&gt;level: &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="ss"&gt;:one&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:two&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:three&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;

  &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;Rediscord&lt;/span&gt;
  &lt;span class="n"&gt;redis_set&lt;/span&gt; &lt;span class="ss"&gt;key: &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;&lt;span class="s2"&gt;"level_&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;level&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;_topic_set"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="ss"&gt;redis: &lt;/span&gt;&lt;span class="no"&gt;REDIS&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;有兴趣的可以去看看 &lt;a href="https://github.com/kikyous/rediscord" rel="nofollow" target="_blank"&gt;https://github.com/kikyous/rediscord&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;接下来需要记录用户答过的题目，依然使用 set&lt;/p&gt;
&lt;h2 id="用户每次答对的题目id塞进 redis 里面"&gt;用户每次答对的题目 id 塞进 redis 里面&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;REDIS.sadd("user_#{current_user.id}_topic_set",  topic_ids)&lt;/code&gt;&lt;/p&gt;
&lt;table class="table table-bordered table-striped"&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;th&gt;Key&lt;/th&gt;
&lt;th&gt;Members&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;user_1_topic_set&lt;/td&gt;
&lt;td&gt;[x, xx, xxx,  ...]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;user_2_topic_set&lt;/td&gt;
&lt;td&gt;[x, xx, xxx,  ...]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;user_10_topic_set&lt;/td&gt;
&lt;td&gt;[x, xx, xxx,  ...]&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2 id="按规则为id 为1的用户取一道level one的题"&gt;按规则为 id 为 1 的用户取一道 level one 的题&lt;/h2&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;left_topics = "user_1_left_topic_set"
REDIS.sdiffstore left_topics, "level_one_topic_set", "user_1_topic_set"
REDIS.srandmember left_topics, 1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;就是把 level_one_topic_set 和用户已经答过的题的 id 集合 "user_1_topic_set" 做一个 diff，并保存在一个 set &lt;code&gt;user_1_left_topic_set&lt;/code&gt; 里面
然后利用 srandmember 从这个 set 里面随机取一个题目 id&lt;/p&gt;

&lt;p&gt;剩下的两个等级同上。&lt;/p&gt;</description>
      <author>kikyous</author>
      <pubDate>Wed, 03 Aug 2016 18:09:26 +0800</pubDate>
      <link>https://ruby-china.org/topics/30720</link>
      <guid>https://ruby-china.org/topics/30720</guid>
    </item>
    <item>
      <title>Rediscord: 在 redis set/zset 中同步数据主键</title>
      <description>&lt;h2 id="Rediscord https://github.com/kikyous/rediscord"&gt;Rediscord &lt;a href="https://github.com/kikyous/rediscord" rel="nofollow" target="_blank"&gt;https://github.com/kikyous/rediscord&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;keep record id sync with dynamic redis set or zset&lt;/p&gt;
&lt;h2 id="Install"&gt;Install&lt;/h2&gt;
&lt;p&gt;add &lt;code&gt;gem 'rediscord'&lt;/code&gt; to Gemfile, and run &lt;code&gt;bundle install&lt;/code&gt;&lt;/p&gt;
&lt;h2 id="Example"&gt;Example&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;set
```ruby
class Post &amp;lt; ApplicationRecord
enum level: [ :one, :two, :there ]&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;include Rediscord
  redis_set key: -&amp;gt;(m){ "level_#{m.level}_post_set" }, redis: Redis.new
end&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;```ruby
Post.create(level: :one)   # id: 1
Post.create(level: :one)   # id: 2
Post.create(level: :two)   # id: 3
Post.create(level: :there) # id: 4
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;what's in redis?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;img src="http://ww1.sinaimg.cn/large/006tKfTcjw1f6gc1feycqj31hc0vsdix.jpg" title="" alt=""&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;zset&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="nc"&gt;Post&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationRecord&lt;/span&gt;
  &lt;span class="n"&gt;enum&lt;/span&gt; &lt;span class="ss"&gt;level: &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="ss"&gt;:one&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:two&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:there&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;

  &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;Rediscord&lt;/span&gt;
  &lt;span class="n"&gt;redis_zset&lt;/span&gt; &lt;span class="ss"&gt;key: &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt; &lt;span class="s2"&gt;"level_&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;level&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;_post_zset"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="ss"&gt;score: &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;updated_at&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_i&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="ss"&gt;redis: &lt;/span&gt;&lt;span class="no"&gt;Redis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Post&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="ss"&gt;level: :one&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;Post&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="ss"&gt;level: :one&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;Post&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="ss"&gt;level: :two&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;Post&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="ss"&gt;level: :there&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src="http://ww1.sinaimg.cn/large/006tKfTcjw1f6gc6mmk9sj31hc0vsgov.jpg" title="" alt=""&gt;&lt;/p&gt;</description>
      <author>kikyous</author>
      <pubDate>Wed, 03 Aug 2016 10:52:29 +0800</pubDate>
      <link>https://ruby-china.org/topics/30708</link>
      <guid>https://ruby-china.org/topics/30708</guid>
    </item>
    <item>
      <title>建议去掉登录验证码</title>
      <description>&lt;p&gt;这样的验证码基本只能给人带来麻烦，挡不住机器的&lt;/p&gt;</description>
      <author>kikyous</author>
      <pubDate>Wed, 20 Jul 2016 09:44:43 +0800</pubDate>
      <link>https://ruby-china.org/topics/30571</link>
      <guid>https://ruby-china.org/topics/30571</guid>
    </item>
    <item>
      <title>&lt;input name="utf8" type="hidden" value="✓"/&gt; 的作用</title>
      <description>&lt;blockquote&gt;
&lt;p&gt;By default, older versions of IE (&amp;lt;=8) will submit form data in Latin-1 encoding if possible. By including a character that can't be expressed in Latin-1, IE is forced to use UTF-8 encoding for its form submissions, which simplifies various backend processes, for example database persistence.&lt;/p&gt;

&lt;p&gt;If the parameter was instead utf8=true then this wouldn't trigger the UTF-8 encoding in these browsers.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="http://programmers.stackexchange.com/questions/168751/is-the-use-of-utf8-preferable-to-utf8-true" rel="nofollow" target="_blank"&gt;http://programmers.stackexchange.com/questions/168751/is-the-use-of-utf8-preferable-to-utf8-true&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;一直不知道这个有什么用 &lt;img title=":sweat_smile:" alt="😅" src="https://twemoji.ruby-china.com/2/svg/1f605.svg" class="twemoji"&gt; &lt;/p&gt;</description>
      <author>kikyous</author>
      <pubDate>Fri, 08 Jul 2016 14:49:33 +0800</pubDate>
      <link>https://ruby-china.org/topics/30479</link>
      <guid>https://ruby-china.org/topics/30479</guid>
    </item>
    <item>
      <title>记事本编辑器是不是应该和发帖一样</title>
      <description>&lt;p&gt;发帖可以选择/粘贴图片上传，可以快速插入代码片段，记事本那里不行，只能在发帖那里编辑好然后粘贴过去。
😀&lt;/p&gt;</description>
      <author>kikyous</author>
      <pubDate>Thu, 05 May 2016 11:57:44 +0800</pubDate>
      <link>https://ruby-china.org/topics/29915</link>
      <guid>https://ruby-china.org/topics/29915</guid>
    </item>
    <item>
      <title>使用 fabrication 准备测试用数据</title>
      <description>&lt;p&gt;转载自我的博客
&lt;a href="http://kikyo.us/2016/04/28/use-fabrication-to-make-testing-data.html" rel="nofollow" target="_blank"&gt;http://kikyo.us/2016/04/28/use-fabrication-to-make-testing-data.html&lt;/a&gt;&lt;/p&gt;

&lt;hr&gt;

&lt;p&gt;rails 默认用 fixture 创建测试数据，但是 fixture 直接操作数据库，不能利用 ActiveRecord，要创造复杂的数据时就会非常痛苦。
因此出现了 fabrication，factory_giri 等，在这两者中我最终选择了 fabrication，因为它更加灵活，更加优美。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/paulelliott/fabrication" rel="nofollow" target="_blank"&gt;https://github.com/paulelliott/fabrication&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="数据模型"&gt;数据模型&lt;/h2&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Company&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationRecord&lt;/span&gt;
  &lt;span class="n"&gt;has_many&lt;/span&gt; &lt;span class="ss"&gt;:stocks&lt;/span&gt;
  &lt;span class="n"&gt;has_many&lt;/span&gt; &lt;span class="ss"&gt;:staffs&lt;/span&gt;
  &lt;span class="n"&gt;has_many&lt;/span&gt; &lt;span class="ss"&gt;:users&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;through: :staffs&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationRecord&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Product&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationRecord&lt;/span&gt;
  &lt;span class="n"&gt;belongs_to&lt;/span&gt; &lt;span class="ss"&gt;:stock&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Staff&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationRecord&lt;/span&gt;
  &lt;span class="n"&gt;belongs_to&lt;/span&gt; &lt;span class="ss"&gt;:user&lt;/span&gt;
  &lt;span class="n"&gt;belongs_to&lt;/span&gt; &lt;span class="ss"&gt;:company&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Stock&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationRecord&lt;/span&gt;
  &lt;span class="n"&gt;belongs_to&lt;/span&gt; &lt;span class="ss"&gt;:product&lt;/span&gt;
  &lt;span class="n"&gt;belongs_to&lt;/span&gt; &lt;span class="ss"&gt;:company&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="创建数据"&gt;创建数据&lt;/h2&gt;&lt;h2 id="初步"&gt;初步&lt;/h2&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# 定义 company Fabricator&lt;/span&gt;
&lt;span class="no"&gt;Fabricator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:company&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="nb"&gt;name&lt;/span&gt; &lt;span class="p"&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;hex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;contacts&lt;/span&gt; &lt;span class="p"&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;hex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;phone&lt;/span&gt; &lt;span class="s1"&gt;'1111111'&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;irb&lt;span class="o"&gt;(&lt;/span&gt;main&lt;span class="o"&gt;)&lt;/span&gt;:012:0&amp;gt; Fabricate&lt;span class="o"&gt;(&lt;/span&gt;:company&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="c"&gt;#&amp;lt;Company id: 980193688, name: "d153c213e4", contacts: "995add", phone: "1111111", created_at: "2016-04-29 01:40:26", updated_at: "2016-04-29 01:40:26"&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这很简单，不值得一提对吧！&lt;/p&gt;
&lt;h2 id="关联关系"&gt;关联关系&lt;/h2&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# 定义 stock Fabricator&lt;/span&gt;
&lt;span class="no"&gt;Fabricator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:stock&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;product&lt;/span&gt;
  &lt;span class="n"&gt;company&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Fabricator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:staff&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;user&lt;/span&gt;
  &lt;span class="n"&gt;company&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;irb&lt;span class="o"&gt;(&lt;/span&gt;main&lt;span class="o"&gt;)&lt;/span&gt;:007:0&amp;gt; Fabricate&lt;span class="o"&gt;(&lt;/span&gt;:stock&lt;span class="o"&gt;)&lt;/span&gt;
  ...
  SQL &lt;span class="o"&gt;(&lt;/span&gt;0.3ms&lt;span class="o"&gt;)&lt;/span&gt;  INSERT INTO &lt;span class="sb"&gt;`&lt;/span&gt;products&lt;span class="sb"&gt;`&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;name&lt;span class="sb"&gt;`&lt;/span&gt;, &lt;span class="sb"&gt;`&lt;/span&gt;created_at&lt;span class="sb"&gt;`&lt;/span&gt;, &lt;span class="sb"&gt;`&lt;/span&gt;updated_at&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; VALUES &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'44434bee4c'&lt;/span&gt;, &lt;span class="s1"&gt;'2016-04-29 01:42:39'&lt;/span&gt;, &lt;span class="s1"&gt;'2016-04-29 01:42:39'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  SQL &lt;span class="o"&gt;(&lt;/span&gt;0.2ms&lt;span class="o"&gt;)&lt;/span&gt;  INSERT INTO &lt;span class="sb"&gt;`&lt;/span&gt;companies&lt;span class="sb"&gt;`&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;name&lt;span class="sb"&gt;`&lt;/span&gt;, &lt;span class="sb"&gt;`&lt;/span&gt;contacts&lt;span class="sb"&gt;`&lt;/span&gt;, &lt;span class="sb"&gt;`&lt;/span&gt;phone&lt;span class="sb"&gt;`&lt;/span&gt;, &lt;span class="sb"&gt;`&lt;/span&gt;created_at&lt;span class="sb"&gt;`&lt;/span&gt;, &lt;span class="sb"&gt;`&lt;/span&gt;updated_at&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; VALUES &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'01382eb7e5'&lt;/span&gt;, &lt;span class="s1"&gt;'8569b3'&lt;/span&gt;, &lt;span class="s1"&gt;'1111111'&lt;/span&gt;, &lt;span class="s1"&gt;'2016-04-29 01:42:39'&lt;/span&gt;, &lt;span class="s1"&gt;'2016-04-29 01:42:39'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  SQL &lt;span class="o"&gt;(&lt;/span&gt;0.2ms&lt;span class="o"&gt;)&lt;/span&gt;  INSERT INTO &lt;span class="sb"&gt;`&lt;/span&gt;stocks&lt;span class="sb"&gt;`&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;product_id&lt;span class="sb"&gt;`&lt;/span&gt;, &lt;span class="sb"&gt;`&lt;/span&gt;company_id&lt;span class="sb"&gt;`&lt;/span&gt;, &lt;span class="sb"&gt;`&lt;/span&gt;created_at&lt;span class="sb"&gt;`&lt;/span&gt;, &lt;span class="sb"&gt;`&lt;/span&gt;updated_at&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; VALUES &lt;span class="o"&gt;(&lt;/span&gt;298488079, 980193691, &lt;span class="s1"&gt;'2016-04-29 01:42:39'&lt;/span&gt;, &lt;span class="s1"&gt;'2016-04-29 01:42:39'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  ...

&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="c"&gt;#&amp;lt;Stock id: 980193023, product_id: 298488079, company_id: 980193691, created_at: "2016-04-29 01:42:39", updated_at: "2016-04-29 01:42:39"&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;可以看到&lt;code&gt;Fabricate(:stock)&lt;/code&gt;不仅生成了 Stock 记录，还生成了与其关联的 Product 和 Company。&lt;/p&gt;
&lt;h2 id="更复杂的"&gt;更复杂的&lt;/h2&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Fabricator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:company&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="nb"&gt;name&lt;/span&gt; &lt;span class="p"&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;hex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;contacts&lt;/span&gt; &lt;span class="p"&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;hex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;phone&lt;/span&gt; &lt;span class="s1"&gt;'1111111'&lt;/span&gt;

  &lt;span class="n"&gt;staffs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;count: &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt; &lt;span class="no"&gt;Fabricate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:staff&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt; &lt;span class="ss"&gt;role: :admin&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;stocks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;count: &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;attrs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="no"&gt;Fabricate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:stock&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt; &lt;span class="ss"&gt;remark: &lt;/span&gt;&lt;span class="s2"&gt;"stock&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;i&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="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;上面的 Fabricator 会生成了一个完备的公司，包括&lt;code&gt;1+2+2+3+3=11&lt;/code&gt;条记录：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1 个 company&lt;/li&gt;
&lt;li&gt;2 个 staff，与每个 staff 关联的 user&lt;/li&gt;
&lt;li&gt;3 个 stock, 与每个 stock 关联的 product&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="继承"&gt;继承&lt;/h2&gt;
&lt;p&gt;如果每次要生成一个完备的公司都要写上面一大堆，岂不是很烦恼！为什么不直接定义一个表示完备公司的 Fabricator 呢？这个 Fabricator 继承自 Company Fabricator，理所当然。&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Fabricator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:complete_company&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;from: :company&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;staffs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;count: &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt; &lt;span class="no"&gt;Fabricate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:staff&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt; &lt;span class="ss"&gt;role: :admin&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;stocks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;count: &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;attrs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="no"&gt;Fabricate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:stock&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt; &lt;span class="ss"&gt;remark: &lt;/span&gt;&lt;span class="s2"&gt;"stock&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;i&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="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;现在可以使用&lt;code&gt;Fabricate(:complete_company)&lt;/code&gt;来生成一个和上面一样的公司了！&lt;/p&gt;
&lt;h2 id="READ MORE"&gt;READ MORE&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://fabricationgem.org/" rel="nofollow" target="_blank"&gt;http://fabricationgem.org/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/paulelliott/fabrication-site/blob/master/source/index.markdown" rel="nofollow" target="_blank"&gt;https://github.com/paulelliott/fabrication-site/blob/master/source/index.markdown&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <author>kikyous</author>
      <pubDate>Fri, 29 Apr 2016 10:30:40 +0800</pubDate>
      <link>https://ruby-china.org/topics/29881</link>
      <guid>https://ruby-china.org/topics/29881</guid>
    </item>
    <item>
      <title>Rails nested layout</title>
      <description>&lt;p&gt;&lt;a href="http://kikyo.us/2016/04/12/rails-nested-layout.html" rel="nofollow" target="_blank"&gt;http://kikyo.us/2016/04/12/rails-nested-layout.html&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="问题"&gt;问题&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;某 rails 项目 &lt;code&gt;layouts/application.html.erb&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight erb"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"utf-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;http-equiv=&lt;/span&gt;&lt;span class="s"&gt;"X-UA-Compatible"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"IE=edge"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="vi"&gt;@title&lt;/span&gt;  &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"keywords"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="vi"&gt;@keywords&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&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;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"description"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="vi"&gt;@description&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="n"&gt;csrf_meta_tags&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;
    &lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="n"&gt;action_cable_meta_tag&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;

    &lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="n"&gt;stylesheet_link_tag&lt;/span&gt;    &lt;span class="s1"&gt;'application'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;media: &lt;/span&gt;&lt;span class="s1"&gt;'all'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'data-turbolinks-track'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;
    &lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="n"&gt;javascript_include_tag&lt;/span&gt; &lt;span class="s1"&gt;'application'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'data-turbolinks-track'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;footer&amp;gt;&lt;/span&gt;
      ...
    &lt;span class="nt"&gt;&amp;lt;/footer&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;现在需要另一个子 layout，他&lt;code&gt;继承&lt;/code&gt;自 layouts/application.html.erb，又有自己的内容，该怎么办呢？尽量把公共的部分抽出来，然后在不同的 layout 之间共享吗？&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;layouts/main.html.erb&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight erb"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
  &lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="s1"&gt;'head'&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;body&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;"container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="cp"&gt;%&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;"sidebar"&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&amp;gt;&lt;/span&gt;
    &lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="s1"&gt;'footer'&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这样可以解决问题但不完美，没有体现出&lt;code&gt;继承&lt;/code&gt;关系来，如果 layout 复杂，可能需要抽出很多的共享部分出来，而且子模板还是有很多重复的代码。&lt;/p&gt;
&lt;h2 id="嵌套模板"&gt;嵌套模板&lt;/h2&gt;
&lt;p&gt;在&lt;code&gt;application_helper.rb&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;parent_layout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="vi"&gt;@view_flow.set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:layout&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;output_buffer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:file&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"layouts/&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;layout&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="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;output_buffer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;ActionView&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;OutputBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;output&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;p&gt;然后&lt;code&gt;layouts/main.html.erb&lt;/code&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;"container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="cp"&gt;%&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;"sidebar"&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&amp;gt;&lt;/span&gt;

&lt;span class="cp"&gt;&amp;lt;%&lt;/span&gt; &lt;span class="n"&gt;parent_layout&lt;/span&gt; &lt;span class="s2"&gt;"application"&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;直接在子模板中指定父模板，完美的继承关系，而且可以进行多次，比如&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;layouts/profile.html.erb&lt;/code&gt;&lt;/li&gt;
&lt;/ul&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;"profile"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="s1"&gt;'profile_nav'&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;
  &lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="cp"&gt;&amp;lt;%&lt;/span&gt; &lt;span class="n"&gt;parent_layout&lt;/span&gt; &lt;span class="s2"&gt;"main"&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;最后这 3 个 layout 的关系如下：&lt;/p&gt;

&lt;p&gt;&lt;code&gt;application &amp;lt; main &amp;lt; profile&lt;/code&gt;&lt;/p&gt;
&lt;h2 id="Reference"&gt;Reference&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://m.onkey.org/nested-layouts" rel="nofollow" target="_blank"&gt;http://m.onkey.org/nested-layouts&lt;/a&gt;&lt;/p&gt;</description>
      <author>kikyous</author>
      <pubDate>Tue, 12 Apr 2016 16:45:48 +0800</pubDate>
      <link>https://ruby-china.org/topics/29678</link>
      <guid>https://ruby-china.org/topics/29678</guid>
    </item>
    <item>
      <title>分享一下 3ds 新绘心教室的作品</title>
      <description>&lt;h2 id="新绘心教室"&gt;新绘心教室&lt;/h2&gt;
&lt;p&gt;新绘心教室是一款教你画画的游戏 
前几天 3ds 上面新绘心教室汉化发布了，于是装上去玩玩，这是这几天的成果&lt;/p&gt;
&lt;h2 id="第一课 樱桃"&gt;第一课 樱桃&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/2016/6c24ec0932da613c2c66c234d4e023a1.png" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;就是跟着教程走，很简单，用什么颜色，怎么画都有演示，最后出来的效果很是让我很吃惊，发给朋友都不相信是我画的。&lt;/p&gt;
&lt;h2 id="第二课 郁金香"&gt;第二课 郁金香&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/2016/a8aded8974d76e83496faad06a81b664.png" title="" alt=""&gt;&lt;/p&gt;
&lt;h2 id="第三课 大树素描"&gt;第三课 大树素描&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/2016/88957b1b8dd9140ebac409dd6a995ad8.png" title="" alt=""&gt;&lt;/p&gt;
&lt;h2 id="第四课 哈密瓜"&gt;第四课 哈密瓜&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/2016/5324d03e7d7efcf5cc553f936577fd5d.png" title="" alt=""&gt;
盘子都画不圆&lt;/p&gt;
&lt;h2 id="第五课 风车"&gt;第五课 风车&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/2016/be1d0ae3fb61ad0f86279e6ff3b4385a.png" title="" alt=""&gt;&lt;/p&gt;
&lt;h2 id="第六课 麦田"&gt;第六课 麦田&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/2016/62d97165b0a417eca06c1fa67e169980.png" title="" alt=""&gt;&lt;/p&gt;
&lt;h2 id="第七课 鲤鱼"&gt;第七课 鲤鱼&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/2016/122c8d373a58769d7ef76abe7d438787.png" title="" alt=""&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;</description>
      <author>kikyous</author>
      <pubDate>Sun, 10 Apr 2016 00:34:34 +0800</pubDate>
      <link>https://ruby-china.org/topics/29643</link>
      <guid>https://ruby-china.org/topics/29643</guid>
    </item>
    <item>
      <title>Puma 还是有问题, 不稳定</title>
      <description>&lt;p&gt;做了一个小应用，部署在 daocloud 上，之前用的是 puma，运行时日志随机出现&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2016-02-29 01:21:57:[App/0] 17:21:57 web.1   | EFAULT
2016-02-29 01:21:57:[App/0] 17:21:57 web.1   | 
2016-02-29 01:21:58:[App/0] 17:21:57 web.1   | ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-linux]
2016-02-29 01:21:58:[App/0] 17:21:57 web.1   | 
2016-02-29 01:21:58:[App/0] 17:21:57 web.1   | [NOTE]
2016-02-29 01:21:58:[App/0] 17:21:57 web.1   | You may have encountered a bug in the Ruby interpreter or extension libraries.
2016-02-29 01:21:58:[App/0] 17:21:57 web.1   | Bug reports are welcome.
2016-02-29 01:21:58:[App/0] 17:21:57 web.1   | For details: http://www.ruby-lang.org/bugreport.html
2016-02-29 01:21:58:[App/0] 17:21:57 web.1   | 
2016-02-29 01:22:02:[App/0] 17:22:02 web.1   | [9] - Worker 0 (pid: 104) booted, phase: 0
2016-02-29 01:22:02:[App/0] 17:22:02 web.1   | [9] - Worker 1 (pid: 107) booted, phase: 0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;要命的是每过一两天程序就没响应了，只能重启 container, 换成 ruby2.2 也一样 , 到网上搜了一下，类似的问题存在好久了
&lt;a href="https://github.com/puma/puma/issues/554" rel="nofollow" target="_blank"&gt;https://github.com/puma/puma/issues/554&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;最后换成 unicorn 运行三天多了，没出现问题。&lt;/p&gt;

&lt;p&gt;不过公司的网站用的 puma 就很稳定，没出现什么问题&lt;/p&gt;</description>
      <author>kikyous</author>
      <pubDate>Wed, 02 Mar 2016 19:53:48 +0800</pubDate>
      <link>https://ruby-china.org/topics/29181</link>
      <guid>https://ruby-china.org/topics/29181</guid>
    </item>
    <item>
      <title>大家来看看这个是 Rails 的 bug 吗？</title>
      <description>&lt;p&gt;&lt;a href="https://github.com/rails/rails/issues/23438" rel="nofollow" target="_blank"&gt;https://github.com/rails/rails/issues/23438&lt;/a&gt;&lt;/p&gt;</description>
      <author>kikyous</author>
      <pubDate>Wed, 03 Feb 2016 09:43:15 +0800</pubDate>
      <link>https://ruby-china.org/topics/28942</link>
      <guid>https://ruby-china.org/topics/28942</guid>
    </item>
  </channel>
</rss>
