<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>yesmeck (Meck)</title>
    <link>https://ruby-china.org/yesmeck</link>
    <description></description>
    <language>en-us</language>
    <item>
      <title>利用快照来测试 Controller 和 View</title>
      <description>&lt;p&gt;Facebook 出品的一个 js 测试框架 &lt;a href="http://facebook.github.io/jest" rel="nofollow" target="_blank" title=""&gt;Jest&lt;/a&gt; 最近推出一个&lt;a href="http://facebook.github.io/jest/blog/2016/07/27/jest-14.html" rel="nofollow" target="_blank" title=""&gt;新功能&lt;/a&gt;，给第一次跑测试的结果生成一个快照，后面就可以用这个快照来保证代码不会被搞坏。&lt;/p&gt;

&lt;p&gt;受 Jest 的启发，我觉得这个快照测试也可以用到 Rails 的 controller 和 view 测试中来，见 &lt;a href="https://github.com/yesmeck/rspec-snapshot" rel="nofollow" target="_blank"&gt;https://github.com/yesmeck/rspec-snapshot&lt;/a&gt;。&lt;/p&gt;

&lt;p&gt;拿 Ruby China 的测试举个🌰，比如这个&lt;a href="https://github.com/ruby-china/ruby-china/blob/3b9cb794d821b816428019dd29edd05f02979e18/spec/api/users_spec.rb#L132-L141" rel="nofollow" target="_blank" title=""&gt;测试&lt;/a&gt;，利用 rspec-snapshot 的话可以写成这样：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s1"&gt;'should work'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="vi"&gt;@replies&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;create_list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:reply&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="ss"&gt;user: &lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;topic: &lt;/span&gt;&lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="s2"&gt;"/api/v3/users/&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;login&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/replies.json"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;offset: &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;limit: &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;

  &lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;body&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;match_snapshot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'users/:login/replies'&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;/p&gt;</description>
      <author>yesmeck</author>
      <pubDate>Mon, 05 Sep 2016 12:02:15 +0800</pubDate>
      <link>https://ruby-china.org/topics/30986</link>
      <guid>https://ruby-china.org/topics/30986</guid>
    </item>
    <item>
      <title>Feeble - 基于 React/Redux 的框架</title>
      <description>&lt;p&gt;Redux 虽然好用但是代码写起来会有很多 boilerplate，配置也很麻烦，官方亦没有推荐的代码组织方式（action、reducer、selector 这些怎么组织）。于是根据大半年的实践，写了这个。由于是一个人鼓捣出来了，需要有更多的反馈。&lt;/p&gt;

&lt;p&gt;&lt;img title=":point_right:" alt="👉" src="https://twemoji.ruby-china.com/2/svg/1f449.svg" class="twemoji"&gt;  &lt;a href="https://github.com/tianche/feeble" rel="nofollow" target="_blank"&gt;https://github.com/tianche/feeble&lt;/a&gt;&lt;/p&gt;</description>
      <author>yesmeck</author>
      <pubDate>Wed, 03 Aug 2016 16:49:34 +0800</pubDate>
      <link>https://ruby-china.org/topics/30717</link>
      <guid>https://ruby-china.org/topics/30717</guid>
    </item>
    <item>
      <title>Bundler 的作用及原理</title>
      <description>&lt;p&gt;原文：&lt;a href="http://bundler.io/rationale.html" rel="nofollow" target="_blank"&gt;http://bundler.io/rationale.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;首先，你要在你应用根目录下一个叫&lt;code&gt;Gemfile&lt;/code&gt;文件里声明这些依赖，它看起来是这个样子的：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;source&lt;/span&gt; &lt;span class="s1"&gt;'https://rubygems.org'&lt;/span&gt;

&lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;'rails'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'4.1.0.rc2'&lt;/span&gt;
&lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;'rack-cache'&lt;/span&gt;
&lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;'nokogiri'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'~&amp;gt; 1.6.1'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这个&lt;code&gt;Gemfile&lt;/code&gt;说明了这些事情：&lt;/p&gt;

&lt;p&gt;首先，他告诉 bundler 默认是在&lt;code&gt;Gemfile&lt;/code&gt;里指定的&lt;code&gt;https://rubygems.org&lt;/code&gt;上来找 gem。如果你的一些 gem 需要从一个私有的 gem 服务器上获取，那么你可以为这些 gem 覆盖掉这个默认的源设置。&lt;/p&gt;

&lt;p&gt;接着，你声明了一些依赖：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;版本是&lt;code&gt;4.1.0.rc2&lt;/code&gt;的&lt;code&gt;rails&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;任意版本的&lt;code&gt;rack-cache&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;版本是&lt;code&gt;&amp;gt;= 1.6.1&lt;/code&gt;但是&lt;code&gt;&amp;lt; 1.7.0&lt;/code&gt;的&lt;code&gt;nokogiri&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;在你第一次声明完依赖后，你要告诉 bundler 去获取它们：&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;bundle &lt;span class="nb"&gt;install&lt;/span&gt;    &lt;span class="c"&gt;# 也可以直接运行 'bundle'，相当于 'bundle install'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Bundler 会连接&lt;code&gt;rubygems.org&lt;/code&gt;（或者其他你声明的源），然后列出所有你指定的符合你需要的 gem。因为所有你在&lt;code&gt;Gemfile&lt;/code&gt;里的依赖有它们自己的依赖，所以基于上面的&lt;code&gt;Gemfile&lt;/code&gt;运行&lt;code&gt;bundle install&lt;/code&gt;会安装相当多的的 gem。&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;bundle &lt;span class="nb"&gt;install
&lt;/span&gt;Fetching gem metadata from https://rubygems.org/.........
Fetching additional metadata from https://rubygems.org/..
Resolving dependencies...
Using rake 10.3.1
Using json 1.8.1
Installing minitest 5.3.3
Installing i18n 0.6.9
Installing thread_safe 0.3.3
Installing builder 3.2.2
Installing rack 1.5.2
Installing erubis 2.7.0
Installing mime-types 1.25.1
Using bundler 1.6.2
Installing polyglot 0.3.4
Installing arel 5.0.1.20140414130214
Installing hike 1.2.3
Installing mini_portile 0.5.3
Installing multi_json 1.9.3
Installing thor 0.19.1
Installing tilt 1.4.1
Installing tzinfo 1.1.0
Installing rack-test 0.6.2
Installing rack-cache 1.2
Installing treetop 1.4.15
Installing sprockets 2.12.1
Installing activesupport 4.1.0.rc2
Installing mail 2.5.4
Installing actionview 4.1.0.rc2
Installing activemodel 4.1.0.rc2
Installing actionpack 4.1.0.rc2
Installing activerecord 4.1.0.rc2
Installing actionmailer 4.1.0.rc2
Installing sprockets-rails 2.0.1
Installing railties 4.1.0.rc2
Installing rails 4.1.0.rc2
Installing nokogiri 1.6.1
Your bundle is &lt;span class="nb"&gt;complete&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
Use &lt;span class="sb"&gt;`&lt;/span&gt;bundle show &lt;span class="o"&gt;[&lt;/span&gt;gemname]&lt;span class="sb"&gt;`&lt;/span&gt; to see where a bundled gem is installed.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果任何需要的 gem 已经被安装了，bundler 会直接使用它们。在你的系统上安装完所有的 gem 后，bundler  会写一个所有这些 gem 和它们的版本号的快照到 Gemfile.lock 里。&lt;/p&gt;
&lt;h2 id="配置你的应用使用 Bundler"&gt;配置你的应用使用 Bundler&lt;/h2&gt;
&lt;p&gt;Bundler 保证 Ruby 能找到&lt;code&gt;Gemfile&lt;/code&gt;里的所有 gem 和这些 gem 自己的依赖。如果你的应用是个 Rails 3 以上的应用的话，你的应用默认已经有运行 bundler 的代码了。如果是 Rails 2.3 的应用，可以看&lt;a href="http://bundler.io/rails23.html" rel="nofollow" target="_blank" title=""&gt;在 Rails 2.3 中设置 Bundler&lt;/a&gt;。&lt;/p&gt;

&lt;p&gt;对于另外的应用来说（比如说基于 Sinatra 的应用），你需要在你引用任何 gem 之前配置一下 bundler。在你应用加载的第一个文件的第一行（对于 Sinatra, 就是写着&lt;code&gt;require 'sinatra'&lt;/code&gt;的那个文件）加入以下下代码：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'rubygems'&lt;/span&gt; &lt;span class="c1"&gt;# Ruby 1.8 以后的版本不再需要这句（楼主注）&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'bundle/setup'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这样 bundler 就能自动找到你的&lt;code&gt;Gemfile&lt;/code&gt;，并且让你&lt;code&gt;Gemfile&lt;/code&gt;里的所有 gem 是可用的（从技术上讲，就是把这些 gem 放到&lt;code&gt;$LOAD_PATH&lt;/code&gt;里）。&lt;/p&gt;

&lt;p&gt;现在你的代码就可以运行了，你可以引用你需要的 gem。比如说你可以&lt;code&gt;require 'sinatra'&lt;/code&gt;。如果你有很多依赖，你可能希望“引用所有我&lt;code&gt;Gemfile&lt;/code&gt;的 gem”。如果要这样做的话，可以把下面这行代码放到&lt;code&gt;require 'bundler/setup'&lt;/code&gt;的下一行：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Bundler&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;require&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;/code&gt;&lt;/pre&gt;
&lt;p&gt;对于我们刚才的&lt;code&gt;Gemfile&lt;/code&gt;来说，这行代码相当于：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'rails'&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'rack-cache'&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'nokogiri'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;精明的读者会发现正确引用&lt;code&gt;rack-cache&lt;/code&gt;的方式是&lt;code&gt;rake/cache&lt;/code&gt;，而不是&lt;code&gt;require 'rack-cache&lt;/code&gt;'。为了告诉 bundler 使用&lt;code&gt;require 'rack/cache'&lt;/code&gt;，只要更新你的&lt;code&gt;Gemfie&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;source&lt;/span&gt; &lt;span class="s1"&gt;'https://rubygems.org'&lt;/span&gt;

&lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;'rails'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'4.1.0.rc2'&lt;/span&gt;
&lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;'rack-cache'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;require: &lt;/span&gt;&lt;span class="s1"&gt;'rack/cache'&lt;/span&gt;
&lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;'nokogiri'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'~&amp;gt; 1.6.1'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;对于这么小的一个&lt;code&gt;Gemfile&lt;/code&gt;来说，我们建议你跳过&lt;code&gt;Bundler.require&lt;/code&gt;而是手动引用这些 gem（特别是你还需要在&lt;code&gt;Gemfile&lt;/code&gt;里写一个&lt;code&gt;:require&lt;/code&gt;配置）。对于很大的&lt;code&gt;Gemfile&lt;/code&gt;来说，使用&lt;code&gt;Bundler.require&lt;/code&gt;让你省略了大量重复的依赖引用。&lt;/p&gt;
&lt;h2 id="把你的代码放进版本库"&gt;把你的代码放进版本库&lt;/h2&gt;
&lt;p&gt;在你开发你的应用一段时间后，把应用跟&lt;code&gt;Gemfile&lt;/code&gt;和&lt;code&gt;Gemfile.lock&lt;/code&gt;一起放到版本库里。这样，你的版本库里就有了你的应用最后一次你确定能正常工作时所有的 gem 以及版本号的记录。要记住，尽管你的&lt;code&gt;Gemfile&lt;/code&gt;里只有三个 gem，但是当你去考虑你依赖的 gem 也依赖其他 gem 时，你的应用实际上依赖了大量的 gem，&lt;/p&gt;

&lt;p&gt;这个非常重要：&lt;strong&gt;&lt;code&gt;Gemfile.lock&lt;/code&gt;把你的应用变成一个你的代码跟第三方代码最后一次你确定能正常工作的包。&lt;/strong&gt; 在&lt;code&gt;Gemfile&lt;/code&gt;里确切指定你依赖的第三方代码的版本并不能提供同样的保证，因为 gem 通常给它们自己的依赖声明一个版本号的范围。&lt;/p&gt;

&lt;p&gt;你在同一台机器上再次运行&lt;code&gt;bundle install&lt;/code&gt;的时候，bundler 会发现系统上已经有了你需要的依赖，然后就会跳过安装的过程。&lt;/p&gt;

&lt;p&gt;不要把&lt;code&gt;.bundle&lt;/code&gt;目录放入版本库，以及所有它里面的文件。这些文件在不同的机器上是不同的，主要是用来保存运行&lt;code&gt;bundle install&lt;/code&gt;时的参数。&lt;/p&gt;

&lt;p&gt;如果你运行了&lt;code&gt;bundle pack&lt;/code&gt;，你需要的 gem（除了来源是 git 仓库的 gem 以外）都会被下载到&lt;code&gt;vendor/cache&lt;/code&gt;目录。如果所有你需要的 gem 都在那个目录里而且你把它放进了版本库里，bundler 运行的时候就不需要联网了。这是一个&lt;strong&gt;可选&lt;/strong&gt;的步骤，因为这样做你的版本库就会变得很大。&lt;/p&gt;
&lt;h2 id="与其他开发者共享你的应用"&gt;与其他开发者共享你的应用&lt;/h2&gt;
&lt;p&gt;当你的同事（或者你在另外一台机器上）获取你的代码的时候，它会包含你最近开发时使用的所有第三方代码的确切版本。当&lt;strong&gt;他们&lt;/strong&gt;运行&lt;code&gt;bundle install&lt;/code&gt;，bundler 会找到&lt;code&gt;Gemfile.lock&lt;/code&gt;并跳过解决依赖的步骤，改为安装所有你原来机器上一样的 gem。&lt;/p&gt;

&lt;p&gt;换句话说，你不需要去猜你需要安装什么版本的依赖。在我们刚才用过的栗子里，尽管&lt;code&gt;rake-cache&lt;/code&gt;声明了依赖&lt;code&gt;rack &amp;gt;= 0.4&lt;/code&gt;，但是我们确定他能正常工作在&lt;code&gt;rack 1.5.2&lt;/code&gt;下。即使 Rack 的团队发布了&lt;code&gt;rack 1.5.3&lt;/code&gt;，bundler 还是会安装&lt;code&gt;1.5.2&lt;/code&gt;这个我们已经知道的确切的版本。这为开发者减轻了大量的维护负担，因为所有机器上都运行着同样的第三方代码。&lt;/p&gt;
&lt;h2 id="更新依赖"&gt;更新依赖&lt;/h2&gt;
&lt;p&gt;当然，有时候你可能要更新你的应用依赖的部分 gem。比如说，你想要把&lt;code&gt;rails&lt;/code&gt;升级到&lt;code&gt;4.1.0&lt;/code&gt;。重点是，你只想要升级一个依赖，而不是要重新解决你的所有依赖并且使用所有 gem 最新的版本。在我们栗子里，你只有 3 个依赖，但是即使在这个栗子里，更新任何一个东西都会变得复杂。&lt;/p&gt;

&lt;p&gt;比如说，&lt;code&gt;rails 4.1.0.rc2&lt;/code&gt;依赖&lt;code&gt;actionpack 4.1.0.rc2&lt;/code&gt;，而&lt;code&gt;actionpack&lt;/code&gt;又依赖&lt;code&gt;rack ~&amp;gt; 1.5.2&lt;/code&gt;（意思是&lt;code&gt;&amp;gt;= 1.5.2&lt;/code&gt;且&lt;code&gt;&amp;lt; 1.6.0&lt;/code&gt;)。&lt;code&gt;rack-cache&lt;/code&gt;又依赖&lt;code&gt;rack &amp;gt;= 0.4&lt;/code&gt;。我们假设&lt;code&gt;rails 4.1.0&lt;/code&gt;也依赖&lt;code&gt;rack ~&amp;gt; 1.5.2&lt;/code&gt;，并且在&lt;code&gt;rails 4.1.0&lt;/code&gt;发布后 Rack 团队发布了&lt;code&gt;rack 1.5.3&lt;/code&gt;。&lt;/p&gt;

&lt;p&gt;如果我们为了更新 Rails，天真地更新了所有它依赖的 gem，我们得到了&lt;code&gt;rack 1.5.3&lt;/code&gt;，这刚好满足&lt;code&gt;rails 4.1.0&lt;/code&gt;和&lt;code&gt;rack-cache&lt;/code&gt;的要求。然而我们并没有特别说要更新&lt;code&gt;rack-cache&lt;/code&gt;，它就可能跟&lt;code&gt;rack 1.5.3&lt;/code&gt;不兼容（不管什么原因）。虽然把&lt;code&gt;rack 1.5.2&lt;/code&gt;升级到&lt;code&gt;rack 1.5.3&lt;/code&gt;不会搞坏什么东西，但是类似这种导致更大版本跨度的更新场景也会发生（见下面 [1] 更多讨论）。&lt;/p&gt;

&lt;p&gt;为了避免这个问题，当你更新一个 gem 时，如果有其他 gem 有与它相同的依赖，bundler 就不会更新那个相同的依赖。在上面的栗子里，由于&lt;code&gt;rack-cache&lt;/code&gt;依然依赖&lt;code&gt;rack&lt;/code&gt;，bundler 不会更新&lt;code&gt;rack&lt;/code&gt;。这样保证了更新&lt;code&gt;rails&lt;/code&gt;不会不小心搞坏&lt;code&gt;rack-cache&lt;/code&gt;。由于&lt;code&gt;rails 4.1.0&lt;/code&gt;的依赖&lt;code&gt;actionpack 4.1.0&lt;/code&gt;保留了&lt;code&gt;rack 1.5.2&lt;/code&gt;的兼容，bundler 就不会管它，&lt;code&gt;rack-cache&lt;/code&gt;就会继续工作，尽管它可能面临跟&lt;code&gt;rack 1.5.3&lt;/code&gt;的不兼容。&lt;/p&gt;

&lt;p&gt;由于你一开始声明了依赖&lt;code&gt;rails 4.1.0.rc2&lt;/code&gt;，如果你想要更新到&lt;code&gt;rails 4.1.0&lt;/code&gt;，只要简单地在&lt;code&gt;Gemfile&lt;/code&gt;里更新成&lt;code&gt;gem 'rails', '4.1.0'&lt;/code&gt;并且运行：&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;bundle &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;根据上面地描述，&lt;code&gt;bundle install&lt;/code&gt;总是执行保守地升级，不会更新你没有在&lt;code&gt;Gemfile&lt;/code&gt;里显式更改的 gem（或者它们的依赖）。也就是说你不修改&lt;code&gt;Gemfile&lt;/code&gt;里的&lt;code&gt;rack-cache&lt;/code&gt;，bundler 就会把它 &lt;strong&gt;和它的依赖（rack）&lt;/strong&gt; 当成一个不可修改的整体。如果&lt;code&gt;rails 3.0.0&lt;/code&gt;跟&lt;code&gt;rack-cache&lt;/code&gt;不兼容，bundler 就会显示你的依赖快照（&lt;code&gt;Gemfile.lock&lt;/code&gt;）跟你更新后的&lt;code&gt;Gemfile&lt;/code&gt;之间的冲突。&lt;/p&gt;

&lt;p&gt;如果你更新了你的&lt;code&gt;Gemfile&lt;/code&gt;，并且你的系统上已经有你所有需要的依赖了，当你启动应用的时候 bundler 会透明地更新&lt;code&gt;Gemfile.lock&lt;/code&gt;。举个栗子，如果你把&lt;code&gt;mysql&lt;/code&gt;加到你的&lt;code&gt;Gemfile&lt;/code&gt;里，并且已经在你的系统上安装了，你可以不需要运行&lt;code&gt;bundle install&lt;/code&gt;就能启动你的应用，并且 bundler 会把最近一次正确的配置写到&lt;code&gt;Gemfile.lock&lt;/code&gt;里&lt;/p&gt;

&lt;p&gt;这个功能在你添加或更新依赖很少的 gem 时就会比较方便。在你更新一些比较重要的 gem（比如 &lt;code&gt;rails&lt;/code&gt;）或者有被很多 gem 依赖的 gem（比如&lt;code&gt;rack&lt;/code&gt;）它就可能失败。如果透明更新失败了，你的应用就会启动失败，bundler 会显示错误引导你运行&lt;code&gt;bundle install&lt;/code&gt;。&lt;/p&gt;
&lt;h2 id="不修改 Gemfile 来更新 Gem"&gt;不修改 Gemfile 来更新 Gem&lt;/h2&gt;
&lt;p&gt;有时候，你想要不修改 Gemfile 来更新一个依赖。比如说，你想要更新到最新版本的&lt;code&gt;rack-cache&lt;/code&gt;。而你又没有在&lt;code&gt;Gemfie&lt;/code&gt;里指定&lt;code&gt;rack-cache&lt;/code&gt;的版本，你可能想要周期性地获取&lt;code&gt;rakc-cache&lt;/code&gt;地最新版。那么你可以使用&lt;code&gt;bundle update&lt;/code&gt;命令：&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;bundle update rack-cache
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这个命令会更新&lt;code&gt;rack-cache&lt;/code&gt;和它地依赖更新到&lt;code&gt;Gemfile&lt;/code&gt;里允许地最新版本（在这个栗子里就是更新到最新版本）。它不会修改其地依赖。&lt;/p&gt;

&lt;p&gt;但是它会在需要地时候更新其他 gem 的依赖。举个栗子，如果最新版的&lt;code&gt;rack-cache&lt;/code&gt;指定了依赖&lt;code&gt;rack &amp;gt;= 1.5.2&lt;/code&gt;，bundler 会更新&lt;code&gt;rack&lt;/code&gt;到&lt;code&gt;1.5.2&lt;/code&gt;尽管你没有要求 bundler 更新 &lt;code&gt;rack&lt;/code&gt;。如果 bundler 需要更新一个其他的 gem 依赖的 gem，那么它会在更新完成后告诉你这件事。&lt;/p&gt;

&lt;p&gt;如果你要更新所有 Gemfile 里的 gem 到最新的能用的版本，运行：&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;bundle update
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这个命令会从头开始解决依赖并忽略掉&lt;code&gt;Gemfile.lock&lt;/code&gt;。如果你这么做了，你要准备好&lt;code&gt;git reset --hard&lt;/code&gt;和测试用例。从头解决依赖会有意想不到的结果，特别是一部分你依赖的第三方库在你上一次更新的时候发布了新的版本。&lt;/p&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;&lt;h3 id="一个简单的 Bundler 流程"&gt;一个简单的 Bundler 流程&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;当你第一次创建 Rails 应用的时候，它已经包含了&lt;code&gt;Gemfile&lt;/code&gt;。其他的应用可以运行：&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;bundle init
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;bundle init&lt;/code&gt;命令会创建一个简单的&lt;code&gt;Gemfile&lt;/code&gt;让你编辑。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;下面，添加你的应用需要的 gem。如果你关心部分你需要的 gem 的版本，可以加一个合适的版本约束：&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;source&lt;/span&gt; &lt;span class="s1"&gt;'https://rubygems.org'&lt;/span&gt;

gem &lt;span class="s1"&gt;'sinatra'&lt;/span&gt;, &lt;span class="s1"&gt;'~&amp;gt; 1.3.6'&lt;/span&gt;
gem &lt;span class="s1"&gt;'rack-cache'&lt;/span&gt;
gem &lt;span class="s1"&gt;'rack-bug'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;如果你有 gem 没在你的系统上安装，运行：&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;bundle &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;更新一个 gem 的版本，首先修改 Gemfile：&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;source&lt;/span&gt; &lt;span class="s1"&gt;'https://rubygems.org'&lt;/span&gt;

gem &lt;span class="s1"&gt;'sinatra'&lt;/span&gt;, &lt;span class="s1"&gt;'~&amp;gt; 1.4.5'&lt;/span&gt;
gem &lt;span class="s1"&gt;'rack-cache'&lt;/span&gt;
gem &lt;span class="s1"&gt;'rack-bug'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后运行：&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;bundle &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;如果&lt;code&gt;bundle install&lt;/code&gt;说你的&lt;code&gt;Gemfile&lt;/code&gt;跟&lt;code&gt;Gemfie.lock&lt;/code&gt;之间有冲突，运行：&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;bundle update sinatra
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这个会升级 Sinatra 这个 gem，以及它所有的依赖。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;更新所有你&lt;code&gt;Gemfile&lt;/code&gt;里的 gem 到最新可用的版本，运行：&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;bundle update
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;每当你的&lt;code&gt;Gemfile.lock&lt;/code&gt;变化的时候，把它放入你的版本库。它保存了你的应用能成功运行所依赖的所有第三方代码的确切版本的历史。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;当部署你的代码到测试或者生产服务器的时候，首先运行你的测试（或启动你的本地开发服务器），确定你把&lt;code&gt;Gemfile.lock&lt;/code&gt;放到了版本库里。在远程服务器上，运行：&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;bundle &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--deployment&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="备注"&gt;备注&lt;/h2&gt;
&lt;p&gt;[1] 举个栗子，如果&lt;code&gt;rails 4.1.0&lt;/code&gt;依赖&lt;code&gt;rack 2.0&lt;/code&gt;，这个&lt;code&gt;rack 2.0&lt;/code&gt;满足&lt;code&gt;rack-cache&lt;/code&gt;的依赖，因为它声明了&lt;code&gt;&amp;gt;= 0.4&lt;/code&gt;的依赖。当然你能指责说&lt;code&gt;rack-cache&lt;/code&gt;不指定依赖的最高版本很愚蠢，但是这种情况确实是普遍存在的，而且很多项目声明依赖的时候会发现它们处在一个很尴尬的场面。依赖限制太严（&lt;code&gt;rack = 1.5.1&lt;/code&gt;）就会让你的项目很难兼容其他项目。依赖限制太宽（rack &amp;gt;= 1.0）会在 Rack 发布新版本的时候可能搞坏你的代码。使用这样的依赖声明&lt;code&gt;rack ~&amp;gt; 1.5.2&lt;/code&gt;和 SemVer 兼容的版本号基本上能解决这个问题，但是这也只是一个普遍能接受的方案。由于 RubyGems 有超过十万个库，这个假设在实际应用中可能并不成立。&lt;/p&gt;</description>
      <author>yesmeck</author>
      <pubDate>Tue, 12 May 2015 04:21:10 +0800</pubDate>
      <link>https://ruby-china.org/topics/25530</link>
      <guid>https://ruby-china.org/topics/25530</guid>
    </item>
    <item>
      <title>如何管理 SSH Public Key</title>
      <description>&lt;p&gt;团队没有专职的运维，服务器的部署维护都需要开发人员自己来操作，服务器一多就很难管理大家对服务器的权限。&lt;/p&gt;

&lt;p&gt;之前有过的做法是用密码登录，而且所有服务器密码都一样，所有人都可以登录服务器操作，这样的做法安全性太差。&lt;/p&gt;

&lt;p&gt;还试过禁用密码全部用 SSH Public Key 认证的方式，这样每次有新的服务器或者有新人来，都要放一次 SSH Public Key 到服务器上，如果有人员离职还要去服务器上把相应的 SSH Public Key 删掉，感觉也不安全而且很麻烦。&lt;/p&gt;

&lt;p&gt;不知道大家有没有碰到这样的问题，是怎么解决的，我想应该能有什么工具来管理 SSH Public Key？&lt;/p&gt;</description>
      <author>yesmeck</author>
      <pubDate>Tue, 28 Apr 2015 16:05:43 +0800</pubDate>
      <link>https://ruby-china.org/topics/25357</link>
      <guid>https://ruby-china.org/topics/25357</guid>
    </item>
    <item>
      <title>使用 state_machine 有很多相似的 event 如何 DRY？</title>
      <description>&lt;p&gt;大概代码是这样：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# app/models/concerns/member_state.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;MemberState&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="n"&gt;included&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;state_machine&lt;/span&gt; &lt;span class="ss"&gt;:member_state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;initial: :initial&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;namespace: &lt;/span&gt;&lt;span class="s1"&gt;'member'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="ss"&gt;:event1&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="n"&gt;transition&lt;/span&gt; &lt;span class="ss"&gt;:initial&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:state1&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="ss"&gt;:event2&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="n"&gt;transition&lt;/span&gt; &lt;span class="ss"&gt;:state1&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:state2&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="ss"&gt;:event3&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="n"&gt;transition&lt;/span&gt; &lt;span class="ss"&gt;:state2&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:state3&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="o"&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="c1"&gt;# app/models/concerns/admin_state.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;AdminState&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="n"&gt;included&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;state_machine&lt;/span&gt; &lt;span class="ss"&gt;:admin_state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;initial: :initial&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;namespace: &lt;/span&gt;&lt;span class="s1"&gt;'admin'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="ss"&gt;:event1&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="n"&gt;transition&lt;/span&gt; &lt;span class="ss"&gt;:initial&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:state1&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="ss"&gt;:event2&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="n"&gt;transition&lt;/span&gt; &lt;span class="ss"&gt;:state1&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:state2&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="ss"&gt;:event3&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="n"&gt;transition&lt;/span&gt; &lt;span class="ss"&gt;:state2&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:state3&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="o"&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="c1"&gt;# app/models/order.rb&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Order&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;MemberState&lt;/span&gt;
  &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;AdminState&lt;/span&gt;

  &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;想要重用相同的 event 定义该如何做呢？&lt;/p&gt;</description>
      <author>yesmeck</author>
      <pubDate>Thu, 22 Aug 2013 01:41:11 +0800</pubDate>
      <link>https://ruby-china.org/topics/13507</link>
      <guid>https://ruby-china.org/topics/13507</guid>
    </item>
    <item>
      <title>Rails 4 生成不带 digest 的 assets</title>
      <description>&lt;p&gt;原来 Rails 3 的 &lt;code&gt;assets:precompile&lt;/code&gt; 是会生成不带 digest 的文件的。升级到 Rails 4 后发现不会生成不带 digest 的文件了，有什么办法生成不带 digest 的 assets 呢？&lt;/p&gt;</description>
      <author>yesmeck</author>
      <pubDate>Wed, 17 Jul 2013 01:26:22 +0800</pubDate>
      <link>https://ruby-china.org/topics/12556</link>
      <guid>https://ruby-china.org/topics/12556</guid>
    </item>
    <item>
      <title>豆瓣电台全局快捷键</title>
      <description>&lt;p&gt;不知道大家听不听豆瓣电台，我自己写代码的时候经常听，但是写代码的时候要想切歌还要把窗口换到浏览器再点电台的标签页再点下一首，而且手还要离开键盘，超烦的。。。所以搞了个这个：&lt;a href="https://github.com/yesmeck/douban_fm_hotkey" rel="nofollow" target="_blank"&gt;https://github.com/yesmeck/douban_fm_hotkey&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;然后就可以全局快捷键控制豆瓣电台啦～～～～～～&lt;/p&gt;</description>
      <author>yesmeck</author>
      <pubDate>Wed, 15 May 2013 19:37:26 +0800</pubDate>
      <link>https://ruby-china.org/topics/11009</link>
      <guid>https://ruby-china.org/topics/11009</guid>
    </item>
    <item>
      <title>用 Dropbox  来备份你的 dotfiles</title>
      <description>&lt;p&gt;好像很多人都喜欢把 dotfiles 放到  GitHub 上做备份。我自己觉的每次修改一下还要用 git 提交一下太麻烦。所以一直都用 Dropbox 来做备份。但是还有一个问题就是新装一个系统后要把备份一个一个 link 回去会很麻烦。所以写了个小东西 &lt;a href="https://github.com/yesmeck/dotbox" rel="nofollow" target="_blank"&gt;https://github.com/yesmeck/dotbox&lt;/a&gt; 可以自动把你的 dotfiles 备份到 Dropbox 的目录，然后可以自动的把备份 link 回他们原来的位置。&lt;/p&gt;

&lt;p&gt;还没用 Dropbox？赶紧注册一个啊：&lt;a href="http://db.tt/g0XGgwB" rel="nofollow" target="_blank"&gt;http://db.tt/g0XGgwB&lt;/a&gt;&lt;/p&gt;</description>
      <author>yesmeck</author>
      <pubDate>Thu, 18 Apr 2013 21:24:22 +0800</pubDate>
      <link>https://ruby-china.org/topics/10319</link>
      <guid>https://ruby-china.org/topics/10319</guid>
    </item>
    <item>
      <title>部署 GitLab 到最后配置 nginx 碰到权限问题</title>
      <description>&lt;p&gt;系统是 Arch Linux，按照 &lt;a href="https://wiki.archlinux.org/index.php/Gitlab" rel="nofollow" target="_blank"&gt;https://wiki.archlinux.org/index.php/Gitlab&lt;/a&gt; 配下来前面都没什么问题。用 rails s 服务也能启动。但是后面配 nginx 和 unicorn 就有问题了。
日志显示是这样：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2012/08/23 20:29:22 [crit] 5586#0: *19 connect() to unix:/home/gitlab/gitlab/tmp/sockets/gitlab.socket failed (13: Permission denied) while connecting to upstream, client: 114.222.182.176, server: gitlab.yesmeck.com, request: "GET /favicon.ico HTTP/1.1", upstream: "http://unix:/home/gitlab/gitlab/tmp/sockets/gitlab.socket:/favicon.ico", host: "gitlab.host.com"
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;nginx 的进程&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;root      5585  0.0  0.1   7780   896 ?        Ss   20:18   0:00 nginx: master process nginx
http      5586  0.0  0.3   7912  1684 ?        S    20:18   0:00 nginx: worker process
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;unicorn 的进程&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gitlab    5476  2.1 12.5 139096 64104 ?        Sl   20:17   0:20 unicorn_rails master -c config/unicorn.rb -E production -D                                               
gitlab    5495  0.0 11.6 139096 59516 ?        Sl   20:18   0:00 unicorn_rails worker[0] -c config/unicorn.rb -E production -D                                            
gitlab    5498  0.0 11.6 139096 59516 ?        Sl   20:18   0:00 unicorn_rails worker[1] -c config/unicorn.rb -E production -D
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;/home/gitlab/gitlab/tmp/sockets/gitlab.socket 的权限&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;srwxrwxrwx 1 gitlab gitlab 0 Aug 23 20:17 /home/gitlab/gitlab/tmp/sockets/gitlab.socket
&lt;/code&gt;&lt;/pre&gt;</description>
      <author>yesmeck</author>
      <pubDate>Thu, 23 Aug 2012 20:42:42 +0800</pubDate>
      <link>https://ruby-china.org/topics/5113</link>
      <guid>https://ruby-china.org/topics/5113</guid>
    </item>
    <item>
      <title>[Rails] 这种情况 model 关系该如何处理？</title>
      <description>&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Category&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="n"&gt;has_many&lt;/span&gt; &lt;span class="ss"&gt;:children&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:class_name&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'Category'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:foreign_key&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'parent_id'&lt;/span&gt;
  &lt;span class="n"&gt;belongs_to&lt;/span&gt; &lt;span class="ss"&gt;:parent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:class_name&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'Category'&lt;/span&gt;

  &lt;span class="n"&gt;has_many&lt;/span&gt; &lt;span class="ss"&gt;:products&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;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;
  &lt;span class="n"&gt;belongs_to&lt;/span&gt; &lt;span class="ss"&gt;:category&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="vi"&gt;@category&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Category&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# 怎么样能让这里获取这个分类及其子分类下的所有 products？&lt;/span&gt;
&lt;span class="vi"&gt;@category.products&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;</description>
      <author>yesmeck</author>
      <pubDate>Sat, 18 Aug 2012 14:21:10 +0800</pubDate>
      <link>https://ruby-china.org/topics/5015</link>
      <guid>https://ruby-china.org/topics/5015</guid>
    </item>
    <item>
      <title>安装的 gem 都 Gem::LoadError</title>
      <description>&lt;p&gt;系统是 Arch Linux，按照官网说明装下来没有问题：&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl &lt;span class="nt"&gt;-L&lt;/span&gt; https://get.rvm.io | bash &lt;span class="nt"&gt;-s&lt;/span&gt; stable &lt;span class="nt"&gt;--ruby&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'[[ -s "$HOME/.rvm/scripts/rvm" ]] &amp;amp;&amp;amp; source "$HOME/.rvm/scripts/rvm"'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; ~/.zshrc
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;source&lt;/span&gt; ~/.zshrc
&lt;span class="nv"&gt;$ &lt;/span&gt;rvm use 1.9.2 &lt;span class="nt"&gt;--default&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;但是自此后安装的 gem 都是 &lt;code&gt;Gem::LoadError&lt;/code&gt;：&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;gem &lt;span class="nb"&gt;install &lt;/span&gt;v2ex
&lt;span class="nv"&gt;$ &lt;/span&gt;v2ex
/home/xxx/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/rubygems/dependency.rb:247:in &lt;span class="sb"&gt;`&lt;/span&gt;to_specs&lt;span class="s1"&gt;': Could not find v2ex (&amp;gt;= 0) amongst [] (Gem::LoadError)
    from /home/xxx/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/rubygems/dependency.rb:256:in `to_spec'&lt;/span&gt;
    from /home/xxx/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/rubygems.rb:1231:in &lt;span class="sb"&gt;`&lt;/span&gt;gem&lt;span class="s1"&gt;'
    from /home/xxx/.gem/ruby/1.9.1/bin/v2ex:22:in `&amp;lt;main&amp;gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;或者这样也一样 &lt;code&gt;$ rvm 1.9.2 do gem install huami&lt;/code&gt;。&lt;/p&gt;

&lt;p&gt;另外&lt;code&gt;$ gem list&lt;/code&gt;是空的：&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;gem list

&lt;span class="k"&gt;***&lt;/span&gt; LOCAL GEMS &lt;span class="k"&gt;***&lt;/span&gt;




&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;换用系统上的 Ruby &lt;code&gt;$ rvm use system&lt;/code&gt; 就不会有这个问题。
是我漏了什么吗？  &lt;/p&gt;</description>
      <author>yesmeck</author>
      <pubDate>Mon, 09 Jul 2012 02:28:23 +0800</pubDate>
      <link>https://ruby-china.org/topics/4197</link>
      <guid>https://ruby-china.org/topics/4197</guid>
    </item>
    <item>
      <title>可以显示 Vim 小贴士的插件</title>
      <description>&lt;p&gt;这是我的第一个 vim 插件：&lt;a href="http://www.vim.org/scripts/script.php?script_id=4094" rel="nofollow" target="_blank"&gt;http://www.vim.org/scripts/script.php?script_id=4094&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;可以在每次打开 vim 的时候在下面显示一个 vim 的小贴士。&lt;/p&gt;

&lt;p&gt;虽然插件本身的实现超简单的，但是对于学习 vim 应该会很有帮助。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://raw.github.com/yesmeck/tips.vim/master/screenshot.png" title="" alt="Vim tips screenshot"&gt;&lt;/p&gt;

&lt;p&gt;另外为了配合这个插件，还写了人生中第一个 Rails 应用 &lt;a href="http://vim-tips.org/" rel="nofollow" target="_blank"&gt;http://vim-tips.org/&lt;/a&gt; 来收集 tips，目前上面的内容都是我从 twitter 上找来的 Orz。欢迎大家提交自己的 tips。  &lt;/p&gt;</description>
      <author>yesmeck</author>
      <pubDate>Fri, 08 Jun 2012 00:12:38 +0800</pubDate>
      <link>https://ruby-china.org/topics/3716</link>
      <guid>https://ruby-china.org/topics/3716</guid>
    </item>
  </channel>
</rss>
