<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>dongli1985 (董理)</title>
    <link>https://ruby-china.org/dongli1985</link>
    <description>宝剑锋从磨砺出，梅花香自苦寒来</description>
    <language>en-us</language>
    <item>
      <title>写了一个用于自动化后台创建的 Gem - Carload</title>
      <description>&lt;p&gt;最近几天写了一个 Rails 后台自动化创建的 gem，名叫&lt;a href="https://github.com/dongli/carload" rel="nofollow" target="_blank" title=""&gt;Carload&lt;/a&gt;（装满货物），它同&lt;code&gt;Rails Admin&lt;/code&gt;，&lt;code&gt;ActiveAdmin&lt;/code&gt;和&lt;code&gt;Administrate&lt;/code&gt;干的是同一件事，你要问我为啥不直接用那仨，我也说不出来，就是享受造轮子&lt;img title=":stuck_out_tongue_closed_eyes:" alt="😝" src="https://twemoji.ruby-china.com/2/svg/1f61d.svg" class="twemoji"&gt;。&lt;/p&gt;

&lt;p&gt;我尽可能把重复性工作封装起来，比如配置 Dashboard 使用如下简明的 DSL（我喜欢 DSL。。）：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Dashboard class is used to tell Carload what models are needed to administrated,&lt;/span&gt;
&lt;span class="c1"&gt;# which attributes are shown, etc.&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Dashboard&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Carload&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Dashboard&lt;/span&gt;
  &lt;span class="c1"&gt;# There are two DSL block types:&lt;/span&gt;
  &lt;span class="c1"&gt;#&lt;/span&gt;
  &lt;span class="c1"&gt;#   model :&amp;lt;model_name&amp;gt; do |spec|&lt;/span&gt;
  &lt;span class="c1"&gt;#     # Whether model should be displayed when URL does not specify one&lt;/span&gt;
  &lt;span class="c1"&gt;#     spec.default = &amp;lt;true_or_false&amp;gt;&lt;/span&gt;
  &lt;span class="c1"&gt;#     # List of attributes that can be edited&lt;/span&gt;
  &lt;span class="c1"&gt;#     spec.attributes.permitted = [...]&lt;/span&gt;
  &lt;span class="c1"&gt;#     # List of attributes that will be shown on index page&lt;/span&gt;
  &lt;span class="c1"&gt;#     spec.index_page.shows.attributes = [...]&lt;/span&gt;
  &lt;span class="c1"&gt;#     # List of attributes with search terms that can be searched on index page (using Ransack gem)&lt;/span&gt;
  &lt;span class="c1"&gt;#     spec.index_page.searches.attributes = [ { name: ..., term: ...}, ... ]&lt;/span&gt;
  &lt;span class="c1"&gt;#   end&lt;/span&gt;
  &lt;span class="c1"&gt;#&lt;/span&gt;
  &lt;span class="c1"&gt;#   associate :&amp;lt;model_name_a&amp;gt; =&amp;gt; :&amp;lt;model_name_b&amp;gt;, choose_by: :&amp;lt;attribute_in_model_b&amp;gt;&lt;/span&gt;

  &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="ss"&gt;:product&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;spec&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
    &lt;span class="n"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;attributes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;permitted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="ss"&gt;:name&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;index_page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;shows&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;attributes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="ss"&gt;:name&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;index_page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;searches&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;attributes&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="ss"&gt;name: :name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;term: :cont&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="ss"&gt;:item&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;spec&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;attributes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;permitted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:product_id&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;index_page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;shows&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;attributes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'product.name'&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;index_page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;searches&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;attributes&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="ss"&gt;name: :name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;term: :cont&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s1"&gt;'product.name'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;term: :cont&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="n"&gt;associate&lt;/span&gt; &lt;span class="ss"&gt;:item&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:product&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;choose_by: :name&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后 Carload 就会为你准备如下后台：&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/2016/f62758b167e6d1bc1f55459ad2d53dcd.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;并且还会处理错误哦：&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/2016/bf1c27a50c9987f7bfa2fb3c909d7801.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/2016/9afad7d8b2b747c9730db6aeb4ddd288.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;搜索用的是 Ransack，切页用的是 Kaminari，权限管理用的是 Pundit，所以一切都要自动化起来！不过如果你对页面不满意，需要定制，也是可以的，直接在&lt;code&gt;app/views/dashboard/&amp;lt;model_names&amp;gt;/&lt;/code&gt;目录下创建相应的 erb 文件就行，动作遵循 Rails 规范。&lt;/p&gt;

&lt;p&gt;欢迎大家一起来造轮子！演示戳&lt;a href="https://carload-demo.herokuapp.com/carload/" rel="nofollow" target="_blank" title=""&gt;这里&lt;/a&gt;。&lt;img title=":point_left:" alt="👈" src="https://twemoji.ruby-china.com/2/svg/1f448.svg" class="twemoji"&gt; &lt;/p&gt;

&lt;p&gt;更新：&lt;/p&gt;

&lt;p&gt;在一定假设条件下可以上传图片了：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;使用&lt;code&gt;carrierwave&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;存储图片的属性名称必须是&lt;code&gt;image&lt;/code&gt;，&lt;code&gt;logo&lt;/code&gt;或&lt;code&gt;img&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;这些假设可以慢慢放宽，不过目前先 enjoy 这些吧：&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/2016/d9fc7b42fdcd1a7700faa26a47e037c1.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;TODO List&lt;/p&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>dongli1985</author>
      <pubDate>Fri, 30 Sep 2016 10:23:06 +0800</pubDate>
      <link>https://ruby-china.org/topics/31210</link>
      <guid>https://ruby-china.org/topics/31210</guid>
    </item>
    <item>
      <title>写了一个 upload-image gem，欢迎拍砖</title>
      <description>&lt;p&gt;上传、裁剪图片在 Rails 中不是很难实现，但是想要优雅地完成也不是那么一两下就搞的定，因此我将相关代码封装成一个 gem（&lt;a href="https://github.com/dongli/upload-image" rel="nofollow" target="_blank" title=""&gt;upload-image&lt;/a&gt;），里面使用了&lt;code&gt;carrierwave&lt;/code&gt;、&lt;code&gt;mini_magick&lt;/code&gt;、&lt;code&gt;cropper.js&lt;/code&gt;，最终实现一句 erb 就完成此功能：&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;upload_image&lt;/span&gt; &lt;span class="ss"&gt;form: &lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;image_name: :avatar&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;width: &lt;/span&gt;&lt;span class="mi"&gt;150&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;height: &lt;/span&gt;&lt;span class="mi"&gt;150&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;form&lt;/code&gt;就是那个 form 对象，&lt;code&gt;image_name&lt;/code&gt;是 model 中对应的图片 column 名称，&lt;code&gt;width&lt;/code&gt;和&lt;code&gt;height&lt;/code&gt;就是显示的尺寸。&lt;/p&gt;

&lt;p&gt;效果图为：&lt;/p&gt;

&lt;p&gt;&lt;img src="http://7xvqi7.com1.z0.glb.clouddn.com/upload_image_snapshot-1.png" title="" alt=""&gt;
&lt;img src="http://7xvqi7.com1.z0.glb.clouddn.com/upload_image_snapshot-2.png" title="" alt=""&gt;
&lt;img src="http://7xvqi7.com1.z0.glb.clouddn.com/upload_image_snapshot-3.png" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;不过有个小问题，这个 gem 里有 js 脚本，现在用的&lt;code&gt;ready&lt;/code&gt;事件，在新的 Turbolinks 5 中跳转不好使，需要使用&lt;code&gt;turbolinks:load&lt;/code&gt;，但是这样以来对之前的 Rails 应用应该也有影响了。&lt;/p&gt;</description>
      <author>dongli1985</author>
      <pubDate>Tue, 30 Aug 2016 14:22:23 +0800</pubDate>
      <link>https://ruby-china.org/topics/30935</link>
      <guid>https://ruby-china.org/topics/30935</guid>
    </item>
    <item>
      <title>一键安装 Nginx 和 Passenger</title>
      <description>&lt;p&gt;之前发过一个&lt;a href="https://ruby-china.org/topics/28033" title=""&gt;帖子&lt;/a&gt;介绍我正在做的一个支持多个 OS 的包管理器，最近更新了下 Nginx 和 Passenger 的安装，将用到我自己的一个 Rails 项目的部署，因此想提前拿出分享给大家。&lt;/p&gt;

&lt;p&gt;首先，安装&lt;a href="https://github.com/dongli/packman" rel="nofollow" target="_blank" title=""&gt;packman&lt;/a&gt;，它是一个类似于 Homebrew 一样的包管理器，用 Ruby 写的，DSL 模仿了 Homebrew，但是所有程序都是从头写的。&lt;/p&gt;

&lt;p&gt;然后，安装：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ packman install nginx -with_passenger=true
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;再然后就是设置 nginx.conf 了：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http {
  ...

  passenger_root /opt/software/passenger/5.0.22/libexec; # &amp;lt;-- 自动加入
  passenger_ruby /opt/software/ruby/2.2.3/bin/ruby;      # &amp;lt;- 自动加入

  server {
    listen 80; 
    server_name &amp;lt;...&amp;gt;;
    ...
    root &amp;lt;应用根目录&amp;gt;/public;
    passenger_enabled on; 
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;安装好后启动 nginx：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ packman start nginx
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;关闭 nginx：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ packman stop nginx
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;其它需要的包如 postgresl, redis 的使用类似：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ packman start postgresl redis
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我之所以再写一个包管理器是因为厌倦了不同 OS 上不尽相同的包安装流程，有了 packman 就只用熟悉一套安装流程和控制流程。当然现在有 vagrant，docker，但是在里面还是要安装软件包，总得有先人帮你装好~&lt;/p&gt;</description>
      <author>dongli1985</author>
      <pubDate>Fri, 18 Dec 2015 15:03:32 +0800</pubDate>
      <link>https://ruby-china.org/topics/28448</link>
      <guid>https://ruby-china.org/topics/28448</guid>
    </item>
    <item>
      <title>在 EmberJS 中嵌套路由的模板没有被渲染</title>
      <description>&lt;p&gt;不好意思，我又来问 EmberJS 的问题了~ 实在是时间紧，任务重，文档也到处搜了。我在学习如何设计页面的结构布局，目前涉及到：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;application
|_ home-page
|_ normal-page
  |_ users#index # 问题：没有被渲染
  |_ users#show  # 问题：同上
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;app/router.js&lt;/code&gt;：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Router.map(function() {
  this.route('normal-page', { path: '' }, function() { // 根据https://gist.github.com/alanpeabody/1c2c23293e3d02b1cee1#the-empty-main-route的建议
    this.route('users', function() {
      this.route('show', { path: ':user_id' });
    });
  });
  this.route('home-page', { path: '/' });
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;app/templates/normal-page.hbs&lt;/code&gt;：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;h1&amp;gt;app/templates/normal-page.hbs&amp;lt;/h1&amp;gt;
{{outlet}}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;app/templates/users.hbs&lt;/code&gt;：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;h1&amp;gt;app/templates/users.hbs&amp;lt;/h1&amp;gt;
{{outlet}}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;app/templates/users/index.hbs&lt;/code&gt;：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;h1&amp;gt;app/templates/users/index.hbs&amp;lt;/h1&amp;gt;

&amp;lt;ul&amp;gt;
  {{#each model as |user|}}
    &amp;lt;li&amp;gt;{{user.name}}&amp;lt;/li&amp;gt;
  {{/each}}
&amp;lt;/ul&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;问题是访问&lt;code&gt;/users&lt;/code&gt;后，只显示如下：
&lt;img src="https://l.ruby-china.com/photo/2015/588c2aedbb32bd4803c4944a286e7c1c.png" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;如果不做&lt;code&gt;normal-page&lt;/code&gt;的嵌套则可以：
&lt;img src="https://l.ruby-china.com/photo/2015/5ffc83e41fb8b58fb6d568a12569c162.png" title="" alt=""&gt;&lt;/p&gt;</description>
      <author>dongli1985</author>
      <pubDate>Sun, 06 Dec 2015 10:33:37 +0800</pubDate>
      <link>https://ruby-china.org/topics/28291</link>
      <guid>https://ruby-china.org/topics/28291</guid>
    </item>
    <item>
      <title>如何传给 Ember 组件数组参数</title>
      <description>&lt;p&gt;刚开始接触 Ember，甚至是 JS，因此问的问题可能比较白，请见谅~ 我在 Ember 应用中创建了一个&lt;code&gt;nav-bar&lt;/code&gt;组件，需要在调用时传入菜单条目，我目前是这样设计的：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{{nav-bar
  navItems=[
    { name: '主要特性', link: '#' },
    { name: '关于我们', link: '#' }
  ]
  subnavItems=[
    { name: '合作条款', link: '#' },
    { name: '联系我们', link: '#' }
  ]}}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;但是这俩参数在 hbs 文件中确是&lt;code&gt;undefined&lt;/code&gt;。请问正确的做法是什么呢？&lt;/p&gt;
&lt;h2 id="更新"&gt;更新&lt;/h2&gt;
&lt;p&gt;根据&lt;a href="/aidewoode" class="user-mention" title="@aidewoode"&gt;&lt;i&gt;@&lt;/i&gt;aidewoode&lt;/a&gt;的回答，不能直接传递 JS 对象（就是数组）到 Ember 的组件中，只能传递字符串，因此我目前的做法是：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{{nav-bar
  navItems='[{ "name": "主要特性", "link": "#" }, { "name": "关于我们", "link": "#" }]'
  subnavItems='[{ "name": "使用条款", "link": "#" }, { "name": "联系我们", "link": "#" }]'}}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后修改&lt;code&gt;app/components/nav-bar.js&lt;/code&gt;：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import Ember from 'ember';

export default Ember.Component.extend({
  navItems: [],
  subnavItems: [],
  onInitialization: function() {                                // 
    this.set('navItems', JSON.parse(this.navItems));            //  增加的内容
    this.set('subnavItems', JSON.parse(this.subnavItems));      //
  }.on('init')                                                  //
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;最后在&lt;code&gt;app/templates/components/nav-bar.hbs&lt;/code&gt;中使用&lt;code&gt;navItems&lt;/code&gt;和&lt;code&gt;subnavItems&lt;/code&gt;：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
  &amp;lt;div class="collapse navbar-collapse"&amp;gt;
    &amp;lt;!-- 右侧菜单 --&amp;gt;
    &amp;lt;ul class="nav pull-right"&amp;gt;
      {{#each navItems as |item|}}
        &amp;lt;li&amp;gt;&amp;lt;a href="{{item.link}}"&amp;gt;{{item.name}}&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
      {{/each}}
    &amp;lt;/ul&amp;gt;
    &amp;lt;!-- 底部菜单 --&amp;gt;
    &amp;lt;ul class="subnav"&amp;gt;
      {{#each subnavItems as |item|}}
        &amp;lt;li&amp;gt;&amp;lt;a href="{{item.link}}"&amp;gt;{{item.name}}&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
      {{/each}}
    &amp;lt;/ul&amp;gt;
  &amp;lt;/div&amp;gt;
...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;欢迎给出更好的解决方法！&lt;/p&gt;</description>
      <author>dongli1985</author>
      <pubDate>Sat, 05 Dec 2015 20:17:51 +0800</pubDate>
      <link>https://ruby-china.org/topics/28288</link>
      <guid>https://ruby-china.org/topics/28288</guid>
    </item>
    <item>
      <title>Ember 中的 model 如何和 Rails 中的保持一致</title>
      <description>&lt;p&gt;自己有一个平台项目，做了几个月的 Rails，基本实现了架子，但是后续想要增加交互功能，越写 jquery 越头大，没有章法可言，因此想尝试换用 EmberJS。不过 EmberJS 是一个 MVC 框架，里面也有自己的 model，那么它如何和后端 Rails 保持一致呢？不会要手动修改吧？刚刚接触 EmberJS，看了一些资料，但是还未掌握精髓。&lt;/p&gt;</description>
      <author>dongli1985</author>
      <pubDate>Fri, 04 Dec 2015 10:50:41 +0800</pubDate>
      <link>https://ruby-china.org/topics/28272</link>
      <guid>https://ruby-china.org/topics/28272</guid>
    </item>
    <item>
      <title>Jasny Bootstrap fileinput 的前端验证</title>
      <description>&lt;p&gt;我采用了 Jasny Bootstrap 的&lt;a href="http://www.jasny.net/bootstrap/javascript/#fileinput" rel="nofollow" target="_blank" title=""&gt;Fileinput&lt;/a&gt;上传文件的表单（为了好的用户体验，remote: true 哦，另外我尚未采用高端的前端框架），我需要完成用户上传文件的前端验证。目前后端传来的错误提示已经摆到正确的地方（如下图所示），但是当我点击&lt;code&gt;改变&lt;/code&gt;，并选择其它文件后，文件显示栏中的&lt;code&gt;soi.pdf&lt;/code&gt;并没有被替换为新的文件名称，但是实际文件已经被替换。&lt;/p&gt;

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

&lt;p&gt;我写的显示错误的 JS 函数为：&lt;/p&gt;
&lt;pre class="highlight coffeescript"&gt;&lt;code&gt;&lt;span class="vi"&gt;@&lt;/span&gt;&lt;span class="na"&gt;showValidationError&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;inputName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;errorMessage&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;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"label[for=&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nx"&gt;inputName&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;]"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="na"&gt;attr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'style'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'color: #AA3F44;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"input#&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nx"&gt;inputName&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"input#&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nx"&gt;inputName&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"div.&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nx"&gt;inputName&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"div.&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nx"&gt;inputName&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;input&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;attr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'style'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'border-color: #AA3F44;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;after&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"""
      &amp;lt;p style='color: #AA3F44; margin-top: 5px;' id='&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nx"&gt;inputName&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;-error-message'&amp;gt;
        &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nx"&gt;errorMessage&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;
      &amp;lt;/p&amp;gt;
    """&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="c1"&gt;# 当用户开始编辑时，去除错误显示。&lt;/span&gt;
  &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;bind&lt;/span&gt; &lt;span class="s"&gt;'click keypress'&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;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"label[for=&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nx"&gt;inputName&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;]"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="na"&gt;attr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'style'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'color: #333333;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="na"&gt;attr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'style'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'border-color: #CCCCCC;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"#&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nx"&gt;inputName&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;-error-message"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="na"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;请问怎么解决呢？或者有其它更好的方式吗？我看过&lt;code&gt;client_side_validations-simple_form&lt;/code&gt;，但是它依赖的 simple_form 还停留在很旧的版本。十分感谢！&lt;/p&gt;</description>
      <author>dongli1985</author>
      <pubDate>Tue, 17 Nov 2015 15:49:43 +0800</pubDate>
      <link>https://ruby-china.org/topics/28087</link>
      <guid>https://ruby-china.org/topics/28087</guid>
    </item>
    <item>
      <title>使用 Ruby 编写了另一个 damned 包管理器</title>
      <description>&lt;p&gt;我从去年 8 月份开始，利用业余时间（好吧，其实也占用了工作时间）开发了一个类似 Homebrew 的跨平台（支持 Mac，Linux，Cygwin）的包管理器，也是用 Ruby 写的。为啥要再写一个 damned 包管理器呢？实在是因为本专业（科学计算范畴）对编译器的要求比较多，常常需要用 Intel 或者 PGI 编译器，而一般的包管理器都是默认 GNU 的，而且软件包的版本也是落后不少，导致在一台服务器上经常要手动编译一个软件包，由于有依赖关系，往往还要装一堆烦人的依赖包，如果加上服务器不能够联网，那么就更加不能愉快地玩耍了。&lt;/p&gt;

&lt;p&gt;于是乎，我开始考虑使用 Homebrew，但是这货是生为 Mac 人，死为 Mac 鬼，压根没考虑过 Linux 的感受（虽然有个 Linuxbrew 衍生，但是基本很难用），因此我寻思着用 Ruby 也很多年了，干嘛不实践一把，不就是要用点元编程嘛？我开始翻看 Homebrew 的源程序，看看也没啥特别的，主要是设计 Formula 的 DSL 这块是我没有用过的，学习了一下（好吧，依葫芦画瓢），也整起来~ 最终造了一个名为 PACKMAN（PACMAN 被占用）的包管理器，项目地址是&lt;a href="https://github.com/dongli/packman" rel="nofollow" target="_blank"&gt;https://github.com/dongli/packman&lt;/a&gt;。&lt;/p&gt;

&lt;p&gt;下面是一个包安装流程的例子：&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;Redis&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;PACKMAN&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Package&lt;/span&gt;
  &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="s1"&gt;'http://download.redis.io/releases/redis-3.0.3.tar.gz'&lt;/span&gt;
  &lt;span class="n"&gt;sha1&lt;/span&gt; &lt;span class="s1"&gt;'0e2d7707327986ae652df717059354b358b83358'&lt;/span&gt;
  &lt;span class="n"&gt;version&lt;/span&gt; &lt;span class="s1"&gt;'3.0.3'&lt;/span&gt;

  &lt;span class="n"&gt;label&lt;/span&gt; &lt;span class="ss"&gt;:compiler_insensitive&lt;/span&gt;

  &lt;span class="n"&gt;option&lt;/span&gt; &lt;span class="ss"&gt;:use_jemalloc&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
  &lt;span class="n"&gt;option&lt;/span&gt; &lt;span class="ss"&gt;:config_file&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:string&lt;/span&gt; &lt;span class="c1"&gt;# Default: .../etc/redis.conf&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;install&lt;/span&gt;
    &lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sx"&gt;%W[ 
      PREFIX=&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;prefix&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sx"&gt;
      CC=&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="no"&gt;PACKMAN&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compiler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:c&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;command&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sx"&gt;
    ]&lt;/span&gt;
    &lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s1"&gt;'MALLOC=jemalloc'&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;use_jemalloc?&lt;/span&gt;
    &lt;span class="no"&gt;PACKMAN&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt; &lt;span class="s1"&gt;'make install'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;
    &lt;span class="sx"&gt;%w[run db/redis log]&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nb"&gt;p&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="no"&gt;PACKMAN&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mkdir&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="s1"&gt;'/'&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="no"&gt;PACKMAN&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt; &lt;span class="s1"&gt;'redis.conf'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s1"&gt;'/var/run/redis.pid'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s1"&gt;'/run/redis.pid'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s1"&gt;'dir ./'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'dir '&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s1"&gt;'/db/redis/'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s1"&gt;'# bind 127.0.0.1'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'bind 127.0.0.1'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s1"&gt;'daemonize no'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'daemonize yes'&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;   
    &lt;span class="no"&gt;PACKMAN&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mkdir&lt;/span&gt; &lt;span class="n"&gt;etc&lt;/span&gt; 
    &lt;span class="no"&gt;PACKMAN&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cp&lt;/span&gt; &lt;span class="s1"&gt;'redis.conf'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;etc&lt;/span&gt; 
    &lt;span class="no"&gt;PACKMAN&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cp&lt;/span&gt; &lt;span class="s1"&gt;'sentinel.conf'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="s1"&gt;'/redis-sentinel.conf'&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt; 

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;start&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="n"&gt;config_file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;config_file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:config_file&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;etc&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/redis.conf"&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="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; 
    &lt;span class="no"&gt;PACKMAN&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;bin&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/redis-server &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;config_file&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt; 

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;status&lt;/span&gt;
    &lt;span class="no"&gt;PACKMAN&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;bin&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/redis-cli info"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:skip_error&lt;/span&gt;
    &lt;span class="vg"&gt;$?&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;success?&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="ss"&gt;:on&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="ss"&gt;:off&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt; 

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;stop&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s1"&gt;'already off'&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="ss"&gt;:off&lt;/span&gt;
    &lt;span class="no"&gt;PACKMAN&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;bin&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/redis-cli shutdown"&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;现在 PACKMAN 已经被我们专业的很多同志用了起来，大大减少装软件的痛苦。不过由于周围的人都不是做 IT 的，基本没有 PR 的能力，而且我深知开源软件如果得不到社区的扶植就是等死，所以呢，我还是想回归 Ruby 社区，希望能够得到大家的支持（主要是 PR~）。&lt;/p&gt;

&lt;p&gt;虽然 PACKMAN 起初主要考虑科学计算这块，但是也可以快速安装 Ruby，Postgresql，Redis，Nginx 之类的做网站必须的软件（本人最近也在做个相关的创业工作），而且提供统一的管理接口，比如：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ packman start postgresql
$ packman start redis
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;供具有洁癖的同志们使用。欢迎大家来拍砖！&lt;/p&gt;</description>
      <author>dongli1985</author>
      <pubDate>Thu, 12 Nov 2015 14:24:21 +0800</pubDate>
      <link>https://ruby-china.org/topics/28033</link>
      <guid>https://ruby-china.org/topics/28033</guid>
    </item>
    <item>
      <title>如何在 Engine 中使用主应用的 Concern 路由呢？[半解决]</title>
      <description>&lt;p&gt;我在主应用中有如下路由：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;concern&lt;/span&gt; &lt;span class="ss"&gt;:collectable&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="s1"&gt;'/collect'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'collections#collect'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;as: :collect&lt;/span&gt;
  &lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="s1"&gt;'/uncollect'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'collections#uncollect'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;as: :uncollect&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="n"&gt;resources&lt;/span&gt; &lt;span class="ss"&gt;:articles&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;concerns: :collectable&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我在 engine 中有如下路由：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;resources&lt;/span&gt; &lt;span class="ss"&gt;:experiments&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我希望给&lt;code&gt;experiments&lt;/code&gt;也加上&lt;code&gt;collectable&lt;/code&gt;。如果直接加上&lt;code&gt;concerns: :collectable&lt;/code&gt;显然无法认，我就把上面的&lt;code&gt;concern :collectable do ... end&lt;/code&gt;拷贝到 engine 中，结果 Rails 去找我 engine 下的&lt;code&gt;CollectionsController&lt;/code&gt;，但是又显然不存在。那如何优雅地解决这个问题呢？让程序更加 DRY 一些。&lt;/p&gt;
&lt;h2 id="更新"&gt;更新&lt;/h2&gt;
&lt;p&gt;自己采用了比较 ugly 的解决方法，还是拷贝&lt;code&gt;concer :collectable do ... end&lt;/code&gt;到 engine，针对找不到&lt;code&gt;&amp;lt;engine&amp;gt;::CollectionsController&lt;/code&gt;的错误，我在 engine 的 routes.rb 里添加如下一行：&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;engine&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;::&lt;/span&gt;&lt;span class="no"&gt;CollectionsController&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;CollectionsController&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;就没有问题，虽然不太 DRY，但是管用。如果你有任何建议欢迎提出。&lt;/p&gt;</description>
      <author>dongli1985</author>
      <pubDate>Sun, 06 Sep 2015 14:15:40 +0800</pubDate>
      <link>https://ruby-china.org/topics/27207</link>
      <guid>https://ruby-china.org/topics/27207</guid>
    </item>
    <item>
      <title>MessageBus 如何避免重复 subscribe？</title>
      <description>&lt;p&gt;在使用中发现存在重复&lt;code&gt;subscribe&lt;/code&gt;某频道的情况，如刷新当前页。我的 CoffeeScript 脚本如下：&lt;/p&gt;
&lt;pre class="highlight coffeescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="na"&gt;on&lt;/span&gt; &lt;span class="s"&gt;'page:change'&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;if&lt;/span&gt; &lt;span class="sr"&gt;/\/users\/\d+/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'[id|=message-bus-collection]'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="na"&gt;each&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;not&lt;/span&gt; &lt;span class="nx"&gt;typeIsArray&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;collection_channels&lt;/span&gt;
        &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;collection_channels&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
      &lt;span class="nx"&gt;channel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="na"&gt;attr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="na"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'message-bus-collection-'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'/'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;collection_channels&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;push&lt;/span&gt; &lt;span class="nx"&gt;channel&lt;/span&gt;
      &lt;span class="nx"&gt;MessageBus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;subscribe&lt;/span&gt; &lt;span class="nx"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&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;alert&lt;/span&gt; &lt;span class="s"&gt;"check"&lt;/span&gt;              &lt;span class="c1"&gt;# &amp;lt;------------------ 这个alert显示该回调函数被重复调用。&lt;/span&gt;
        &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"i#&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;collectable_type&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;-&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;collectable_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="na"&gt;show&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nx"&gt;typeIsArray&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;collection_channels&lt;/span&gt;
    &lt;span class="nx"&gt;MessageBus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;unsubscribe&lt;/span&gt; &lt;span class="nx"&gt;channel&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;channel&lt;/span&gt; &lt;span class="o"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;collection_channels&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我觉得应该是检查当前的 client 是否已经订阅，但是不知道怎么做。MessageBus 的文档惜字如金，源程序暂时看不大明白，请教有经验的朋友，十分感谢！&lt;/p&gt;</description>
      <author>dongli1985</author>
      <pubDate>Sat, 05 Sep 2015 23:19:59 +0800</pubDate>
      <link>https://ruby-china.org/topics/27197</link>
      <guid>https://ruby-china.org/topics/27197</guid>
    </item>
    <item>
      <title>如何优雅地使用 Rails Engine？</title>
      <description>&lt;p&gt;我希望将我的应用分为多个模块。目前包括一个基础模块（也是主模块），里面包含用户管理（使用 Devise）、机构管理、博客和评论系统等，还将有一个扩展模块，包括领域特定服务。我希望让使用者（身为管理员）可以选择添加扩展模块，添加后网站上自动加载扩展模块，有相应的数据库模型，视图，控制器等等。目前遇到的问题是在扩展模块中也需要使用到用户信息、机构信息，甚至评论系统。不知道该如何优雅地实现各个功能间的解耦合。&lt;/p&gt;</description>
      <author>dongli1985</author>
      <pubDate>Thu, 13 Aug 2015 15:46:27 +0800</pubDate>
      <link>https://ruby-china.org/topics/26910</link>
      <guid>https://ruby-china.org/topics/26910</guid>
    </item>
    <item>
      <title>acts_as_taggable_on + simple_form + select2 只有最后一个标签被保存 [已解决]</title>
      <description>&lt;p&gt;我使用&lt;code&gt;acts_as_taggable_on&lt;/code&gt;做标签，和&lt;code&gt;simple_form&lt;/code&gt;+&lt;code&gt;select2&lt;/code&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;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;input&lt;/span&gt; &lt;span class="ss"&gt;:category_list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;label: &lt;/span&gt;&lt;span class="kp"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;collection: &lt;/span&gt;&lt;span class="vi"&gt;@article.categories.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;t&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;name&lt;/span&gt; &lt;span class="p"&gt;}&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;select2&lt;/code&gt;调用如下：&lt;/p&gt;
&lt;pre class="highlight coffeescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'#article_category_list'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="na"&gt;select2&lt;/span&gt;
  &lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;
  &lt;span class="na"&gt;multiple&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在输入时显示有两个标签：
&lt;img src="https://l.ruby-china.com/photo/2015/8a00dea177c3e32297ac77bb06fb1bfb.png" title="" alt=""&gt;
当保存按钮被点击时，打印&lt;code&gt;select&lt;/code&gt;元素的值：
&lt;img src="https://l.ruby-china.com/photo/2015/d4327384992e31422474a3fb513a9924.png" title="" alt=""&gt;
保存后却只显示最后一个标签：
&lt;img src="https://l.ruby-china.com/photo/2015/0b2ae2191f8e0fab164d3c25d0a5c0c7.png" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;请问该如何解决呢？&lt;/p&gt;

&lt;p&gt;更新 1：
忘记贴相关日志了：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Started PATCH "/users/1/articles/1" for 127.0.0.1 at 2015-08-11 22:55:17 +0800
Processing by ArticlesController#update as HTML
  Parameters: {"utf8"=&amp;gt;"✓", "authenticity_token"=&amp;gt;"BlU5N1JObvkG6dhL0r98p1ejms0CmdifwFF9FZYuO5/bvsCNNTonhhldhFro94kKqn0KleOjN3VqB9kvWF20pg==", "article"=&amp;gt;{"user_id"=&amp;gt;"1", "title"=&amp;gt;"云滴谱的数值求解", "category_list"=&amp;gt;"第二个标签", "privacy"=&amp;gt;"0", "group_ids"=&amp;gt;[""], "content"=&amp;gt;"\\\\[ \\frac{\\partial n}{\\partial t} = - \\frac{\\partial}{\\partial r} \\frac{d r}{d t} n \\\\]"}, "commit"=&amp;gt;"修改", "user_id"=&amp;gt;"1", "id"=&amp;gt;"1"}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;可见&lt;code&gt;category_list&lt;/code&gt;中只有&lt;code&gt;第二个标签&lt;/code&gt;。&lt;/p&gt;

&lt;p&gt;更新 2：
我将表单输入改为如下形式有效果：&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;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;text_field&lt;/span&gt; &lt;span class="ss"&gt;:category_list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;label: &lt;/span&gt;&lt;span class="kp"&gt;false&lt;/span&gt;
&lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Started PATCH "/users/1/articles/1" for 127.0.0.1 at 2015-08-12 08:01:01 +0800
Processing by ArticlesController#update as HTML
  Parameters: {"utf8"=&amp;gt;"✓", "authenticity_token"=&amp;gt;"RCYsujn6X6taCRUqJLUUUITQOY1HmrJ9DVyz6HtylUA7GFwD/XoHU1MSuDiNrLDO8u+TjooSssmqy3GFuvKdOQ==", "article"=&amp;gt;{"user_id"=&amp;gt;"1", "title"=&amp;gt;"云滴谱的数值求解", "category_list"=&amp;gt;"第二个标记,第三个标记", "privacy"=&amp;gt;"0", "group_ids"=&amp;gt;[""], "content"=&amp;gt;"\\\\[ \\frac{\\partial n}{\\partial t} = - \\frac{\\partial}{\\partial r} \\frac{d r}{d t} n \\\\]"}, "commit"=&amp;gt;"修改", "user_id"=&amp;gt;"1", "id"=&amp;gt;"1"}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;但是表单输入没有&lt;code&gt;select2&lt;/code&gt;那样的分块：
&lt;img src="https://l.ruby-china.com/photo/2015/ddb64b046cbcfd09d880784c2c735d02.png" title="" alt=""&gt;
最接近的一个例子在&lt;a href="https://rcode5.wordpress.com/2013/03/07/acts_as_taggable_on-select2-super-easy-tags-in-rails/" rel="nofollow" target="_blank" title=""&gt;这里&lt;/a&gt;，但是该方法似乎不管用了。&lt;/p&gt;
&lt;h2 id="更新 3（最终版）："&gt;更新 3（最终版）：&lt;/h2&gt;
&lt;p&gt;经过折腾（debugger），终于大概搞清楚问题所在。首先说在更新 2 中，使用了&lt;code&gt;text_field&lt;/code&gt;，此时从表单传回的&lt;code&gt;category_list&lt;/code&gt;是一个字符串，所以在强参数处无需说明&lt;code&gt;category_list&lt;/code&gt;是一个数组，方法有效，但是输入时没有&lt;code&gt;select2&lt;/code&gt;那种分块的好看，因此废弃。在最开始的方法中，使用了&lt;code&gt;select&lt;/code&gt;元素，传回的是数组，因此需要说明&lt;code&gt;category_list&lt;/code&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;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:article&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;permit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;category_list: &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;其次还需要在表单中显式支持&lt;code&gt;multiple: 'multiple'&lt;/code&gt;（正如&lt;a href="/_kaichen" class="user-mention" title="@_kaichen"&gt;&lt;i&gt;@&lt;/i&gt;_kaichen&lt;/a&gt;支持的，但是写&lt;code&gt;multiple: true&lt;/code&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;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;input&lt;/span&gt; &lt;span class="ss"&gt;:category_list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;label: &lt;/span&gt;&lt;span class="kp"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;collection: &lt;/span&gt;&lt;span class="vi"&gt;@article.categories.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;t&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;name&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="ss"&gt;include_blank: &lt;/span&gt;&lt;span class="kp"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;input_html: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="ss"&gt;multiple: &lt;/span&gt;&lt;span class="s1"&gt;'multiple'&lt;/span&gt;     &lt;span class="c1"&gt;# &amp;lt;---------- 这个一定要加&lt;/span&gt;
  &lt;span class="p"&gt;}&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;p&gt;非常感谢各位的帮助！&lt;/p&gt;</description>
      <author>dongli1985</author>
      <pubDate>Tue, 11 Aug 2015 22:01:18 +0800</pubDate>
      <link>https://ruby-china.org/topics/26880</link>
      <guid>https://ruby-china.org/topics/26880</guid>
    </item>
    <item>
      <title>如何使用 Select2 远程 POST 请求 (带参数)？[已解决]</title>
      <description>&lt;p&gt;我需要让用户选择一个群组，但是只能选择他所在的群组。这应该需要向后端请求数据，我做了一个 API，传入一个用户的 ID，就返回他所在的群组，比如：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ curl -d '{"user_id": "1"}' http://localhost:3000/api/v1/groups/for_user -H Content-Type:application/json 
[[1, "测试团队"]]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;之前使用&lt;code&gt;Select2&lt;/code&gt;做了返回所有群组的程序如下：&lt;/p&gt;
&lt;pre class="highlight coffeescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'select[id=input-group-name]'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="na"&gt;select2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="na"&gt;ajax&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ROOT_PATH&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="s"&gt;'api/v1/groups/names'&lt;/span&gt;
    &lt;span class="na"&gt;dataType&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'json'&lt;/span&gt;
    &lt;span class="na"&gt;delay&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;250&lt;/span&gt;
    &lt;span class="na"&gt;processResults&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&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="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;results&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;d&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="na"&gt;text&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;d&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="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="na"&gt;results&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;page&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;results&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;上面使用的是&lt;code&gt;GET&lt;/code&gt;请求，现在需要使用&lt;code&gt;POST&lt;/code&gt;请求，并传入&lt;code&gt;user_id&lt;/code&gt;参数，目前的程序是：&lt;/p&gt;
&lt;pre class="highlight coffeescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'select[id=input-group-name-for-user]'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="na"&gt;select2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="na"&gt;ajax&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'POST'&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-----------------------------------&lt;/span&gt; &lt;span class="err"&gt;将请求改为&lt;/span&gt;&lt;span class="nx"&gt;POST&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ROOT_PATH&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="s"&gt;'api/v1/groups/for_user'&lt;/span&gt;
    &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;contentType&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'application/json; charset=utf-8'&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="na"&gt;dataType&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'json'&lt;/span&gt;
    &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;------------------------------------------&lt;/span&gt; &lt;span class="err"&gt;是在这里传入&lt;/span&gt;&lt;span class="nx"&gt;user_id&lt;/span&gt;&lt;span class="err"&gt;吗？&lt;/span&gt;
    &lt;span class="na"&gt;delay&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;250&lt;/span&gt;
    &lt;span class="na"&gt;processResults&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&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="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;results&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;d&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="na"&gt;text&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;d&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="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="na"&gt;results&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;page&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;results&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;请问该如何传递参数&lt;code&gt;user_id&lt;/code&gt;呢？&lt;/p&gt;

&lt;p&gt;PS：&lt;code&gt;Select2&lt;/code&gt;的设计和文档真心看得头大，完全靠摸索。&lt;/p&gt;

&lt;p&gt;EDIT-1:
我尝试了如下暴力方式：&lt;/p&gt;
&lt;pre class="highlight coffeescript"&gt;&lt;code&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
  &lt;span class="na"&gt;user_id&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/2015/fde0ea8a8cffd88fe2c0cd438133af53.png" title="" alt=""&gt;
但是尝试如下优雅方式时却不行：&lt;/p&gt;
&lt;pre class="highlight coffeescript"&gt;&lt;code&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
  &lt;span class="na"&gt;user_id&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="na"&gt;attr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'user_id'&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;在&lt;code&gt;select&lt;/code&gt;元素上添加&lt;code&gt;data-user-id&lt;/code&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;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;association&lt;/span&gt; &lt;span class="ss"&gt;:groups&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;label: &lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'research_record.public_groups'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="ss"&gt;required: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;label_method: :name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;value_method: :id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;collection: &lt;/span&gt;&lt;span class="vi"&gt;@research_record.groups&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;input_html: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="ss"&gt;id: &lt;/span&gt;&lt;span class="s1"&gt;'input-group-name-for-user'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="ss"&gt;data: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;user_id: &lt;/span&gt;&lt;span class="n"&gt;current_user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;# &amp;lt;------------------------- 这里添加data-user-id属性&lt;/span&gt;
  &lt;span class="p"&gt;}&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;pre class="highlight coffeescript"&gt;&lt;code&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
  &lt;span class="na"&gt;user_id&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'select[id=input-group-name-for-user]'&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="s"&gt;'user-id'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;</description>
      <author>dongli1985</author>
      <pubDate>Wed, 05 Aug 2015 11:15:52 +0800</pubDate>
      <link>https://ruby-china.org/topics/26774</link>
      <guid>https://ruby-china.org/topics/26774</guid>
    </item>
    <item>
      <title>Ruby 与 zlib 库的冲突问题</title>
      <description>&lt;p&gt;我安装了一个&lt;code&gt;ZLIB&lt;/code&gt;，并设置了&lt;code&gt;LD_LIBRARY_PATH&lt;/code&gt;：&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;LD_LIBRARY_PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/opt/soft/zlib/1.2.8/2/lib:&lt;span class="nv"&gt;$LD_LIBRARY_PATH&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后再运行我的一个&lt;code&gt;Ruby&lt;/code&gt;程序就遇到了如下错误：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/opt/soft/packman/ruby/lib/ruby/2.1.0/digest.rb:12:in `const_missing': library not found for class Digest::SHA1 -- digest/sha1 (LoadError)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果把&lt;code&gt;LD_LIBRARY_PATH&lt;/code&gt;清空，则不会遇到这个错误。请问这是什么原因导致的呢？&lt;/p&gt;</description>
      <author>dongli1985</author>
      <pubDate>Tue, 10 Feb 2015 15:18:34 +0800</pubDate>
      <link>https://ruby-china.org/topics/24201</link>
      <guid>https://ruby-china.org/topics/24201</guid>
    </item>
    <item>
      <title>诡异的 uninitialized constant 错误</title>
      <description>&lt;p&gt;我有个程序在很多台电脑上都运行没有问题，但是在一个&lt;code&gt;Ubuntu 11.10，Ruby 2.1.3p242 (2014-09-19 revision 47630) [x86_64-linux]&lt;/code&gt;环境下运行时出现：&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/tp914/zy/packman/packages/wrf_wps.rb:33:in &lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="nb"&gt;install&lt;/span&gt;&lt;span class="s1"&gt;': uninitialized constant Wrf_wps::Jasper (NameError)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;下面是问题脚本的片段：&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;Wrf_wps&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;PACKMAN&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Package&lt;/span&gt;
  &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="s1"&gt;'http://www2.mmm.ucar.edu/wrf/src/WPSV3.6.1.TAR.gz'&lt;/span&gt;
  &lt;span class="n"&gt;sha1&lt;/span&gt; &lt;span class="s1"&gt;'f6ef8b25593d4d5711e7d6853db4965e60969b88'&lt;/span&gt;
  &lt;span class="n"&gt;version&lt;/span&gt; &lt;span class="s1"&gt;'3.6.1'&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;install&lt;/span&gt;
    &lt;span class="no"&gt;PACKMAN&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append_env&lt;/span&gt; &lt;span class="s2"&gt;"NETCDF='&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="no"&gt;PACKMAN&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;prefix&lt;/span&gt; &lt;span class="no"&gt;Netcdf&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="ss"&gt;:ignore&lt;/span&gt;
    &lt;span class="n"&gt;includes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="n"&gt;libs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="n"&gt;includes&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="no"&gt;PACKMAN&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;prefix&lt;/span&gt; &lt;span class="no"&gt;Jasper&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/include"&lt;/span&gt; &lt;span class="c1"&gt;# 出问题的地方&lt;/span&gt;
    &lt;span class="o"&gt;...&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;/code&gt;&lt;/pre&gt;
&lt;p&gt;问题是：为什么 Ruby 会悄悄给 Jasper 前面加上一个前缀&lt;code&gt;Wrf_wps::&lt;/code&gt;呢？&lt;/p&gt;</description>
      <author>dongli1985</author>
      <pubDate>Fri, 09 Jan 2015 15:49:57 +0800</pubDate>
      <link>https://ruby-china.org/topics/23634</link>
      <guid>https://ruby-china.org/topics/23634</guid>
    </item>
    <item>
      <title>关于表达式解析问题</title>
      <description>&lt;p&gt;大家好！我正在开发一个用于 Fortran 程序的编程工具，需要对 Fortran 进行解析。之前用了 Treetop，但是它的文档很稀少，而且很完全掌握，因此我想换用 Parslet，已经写了一些解析规则，放在了（&lt;a href="https://gist.github.com/dongli/5791976" rel="nofollow" target="_blank"&gt;https://gist.github.com/dongli/5791976&lt;/a&gt;）。&lt;/p&gt;

&lt;p&gt;在解析表达式的时候遇到了一点问题，错误可以通过 gist 里的 rspec 脚步看到。希望对文本解析熟悉的同志帮帮忙。多谢！&lt;/p&gt;</description>
      <author>dongli1985</author>
      <pubDate>Sun, 16 Jun 2013 23:13:10 +0800</pubDate>
      <link>https://ruby-china.org/topics/11765</link>
      <guid>https://ruby-china.org/topics/11765</guid>
    </item>
  </channel>
</rss>
