<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>TCnet</title>
    <link>https://ruby-china.org/TCnet</link>
    <description></description>
    <language>en-us</language>
    <item>
      <title>Spree 插件开发总结之八个步骤细节</title>
      <description>&lt;p&gt;用 spree 做电商网站的朋友，会想修改程序来满足自己的需求。当然可以直接下载程序修改，最好的方式是写一个插件来添加和修改自己需要的功能。 &lt;/p&gt;

&lt;p&gt;开始写插件会有很多的问题，我这里把我开发的一个插件 spree_mati 的过程详细记录下，希望可以对开始学习的你有点帮助。 &lt;/p&gt;

&lt;p&gt;插件地址 &lt;a href="https://github.com/TCnet/spree_mati" rel="nofollow" target="_blank"&gt;https://github.com/TCnet/spree_mati&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;参考资料 spree 官网教程：&lt;a href="https://guides.spreecommerce.org/developer/tutorials/extensions_tutorial.html" rel="nofollow" target="_blank"&gt;https://guides.spreecommerce.org/developer/tutorials/extensions_tutorial.html&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;如何安装插件：&lt;a href="https://guides.spreecommerce.org/developer/customization/extensions.html#installing-an-extension" rel="nofollow" target="_blank"&gt;https://guides.spreecommerce.org/developer/customization/extensions.html#installing-an-extension&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;好了 开始我们的插件开发记录： &lt;/p&gt;

&lt;p&gt;这里是苹果系统并安装好了开发环境，一些是终端运行细节。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. 创建插件并打开项目&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;mkdir&lt;/span&gt; &lt;span class="n"&gt;my_extension&lt;/span&gt;

&lt;span class="n"&gt;cd&lt;/span&gt; &lt;span class="n"&gt;my_extension&lt;/span&gt;

&lt;span class="n"&gt;spree&lt;/span&gt; &lt;span class="n"&gt;extension&lt;/span&gt; &lt;span class="n"&gt;spree_mati&lt;/span&gt;

&lt;span class="n"&gt;cd&lt;/span&gt; &lt;span class="n"&gt;spree_mati&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;#这是 textmate 打开项目命令 如果你用其他的编辑器 不需要运行&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;subl&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="c1"&gt;#Gemfile文件添加依赖的gems&lt;/span&gt;
&lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;'roo'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'~&amp;gt; 2.8.0'&lt;/span&gt;
&lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;'roo-xls'&lt;/span&gt;
&lt;span class="n"&gt;bundle&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;2、创建数据库结构和模型&lt;/strong&gt;
A、创建迁移 迁移文件内容见插件代码 db 文件&lt;/p&gt;

&lt;p&gt;在终端执行：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;#记录上传的excel表格&lt;/span&gt;
&lt;span class="n"&gt;bundle&lt;/span&gt; &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="n"&gt;rails&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt; &lt;span class="n"&gt;migration&lt;/span&gt; &lt;span class="n"&gt;create_spree_mati_import&lt;/span&gt;
&lt;span class="c1"&gt;#添加bullet_point 到产品表格&lt;/span&gt;
&lt;span class="n"&gt;bundle&lt;/span&gt; &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="n"&gt;rails&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt; &lt;span class="n"&gt;migration&lt;/span&gt; &lt;span class="n"&gt;add_bullet_point_to_spree_products&lt;/span&gt;
&lt;span class="c1"&gt;#添加standard_price 和 list_price  到产品变体表格&lt;/span&gt;
&lt;span class="n"&gt;bundle&lt;/span&gt; &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="n"&gt;rails&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt; &lt;span class="n"&gt;migration&lt;/span&gt; &lt;span class="n"&gt;add_standard_price_to_spree_variants&lt;/span&gt;
&lt;span class="c1"&gt;#添加亚马逊的产品链接，用于引流到亚马逊下单&lt;/span&gt;
&lt;span class="n"&gt;bundle&lt;/span&gt; &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="n"&gt;rails&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt; &lt;span class="n"&gt;migration&lt;/span&gt; &lt;span class="n"&gt;add_amazon_link_to_spree_products&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;B、数据模型&lt;/p&gt;

&lt;p&gt;在 app/models/spree/ 下新建 模型文件&lt;/p&gt;

&lt;p&gt;mati.rb  #空着预留
mati_import.rb&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Spree&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MatiImport&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Spree&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_one_attached&lt;/span&gt; &lt;span class="ss"&gt;:datafile&lt;/span&gt;  &lt;span class="c1"&gt;#上传文件&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;mati_setting.rb #配置设置文件&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Spree&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MatiSetting&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Spree&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Preferences&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Configuration&lt;/span&gt; 
    &lt;span class="n"&gt;preference&lt;/span&gt; &lt;span class="ss"&gt;:import_row_from_title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:integer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;default: &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;
    &lt;span class="n"&gt;preference&lt;/span&gt; &lt;span class="ss"&gt;:ama_title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;default: &lt;/span&gt;&lt;span class="s2"&gt;"{0} at Aodrusa {1} Clothing store"&lt;/span&gt;
    &lt;span class="n"&gt;preference&lt;/span&gt; &lt;span class="ss"&gt;:ama_description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:string&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;default: &lt;/span&gt;&lt;span class="s2"&gt;"Buy {0} and other {1} at {2}. We Offer New Women's Fashion Clothing Very Frequent"&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;user_decorator.rb#修改用户 记录属于当前操作用户&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Spree::UserDecorator&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;prepended&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;has_many&lt;/span&gt; &lt;span class="ss"&gt;:mati_imports&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class_name: &lt;/span&gt;&lt;span class="s1"&gt;'Spree::MatiImport'&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="no"&gt;Spree&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;prepend&lt;/span&gt; &lt;span class="no"&gt;Spree&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;UserDecorator&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;3、添加设置路由和本地化文件。&lt;/strong&gt;
在 config/routes.rb 添加路由&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Add your extension routes here&lt;/span&gt;
  &lt;span class="n"&gt;namespace&lt;/span&gt; &lt;span class="ss"&gt;:admin&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; 
    &lt;span class="n"&gt;resources&lt;/span&gt; &lt;span class="ss"&gt;:mati_imports&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;member&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="n"&gt;post&lt;/span&gt; &lt;span class="ss"&gt;:importdata&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt; 
    &lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="s1"&gt;'mati_settings'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'mati_settings#edit'&lt;/span&gt;
    &lt;span class="n"&gt;patch&lt;/span&gt; &lt;span class="s1"&gt;'mati_settings'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'mati_settings#update'&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;本地化文件，config/locales/en.html&lt;/p&gt;

&lt;p&gt;添加修改你要用到的文字比如&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="ss"&gt;en:
  spree:
    mati: &lt;/span&gt;&lt;span class="no"&gt;Mati&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在视图文件可以&amp;lt;%= Spree.t('mati') %&amp;gt;来显示 Mati 了&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4、添加 override 文件目录和文件用来添加修改 spree 的文件&lt;/strong&gt;
在 app/overrides/spree/admin 下添加 后台需要添加的文件包括新增菜单导航，修改产品添加页面等。&lt;/p&gt;

&lt;p&gt;这边只列举菜单添加菜单代码，因为这个你肯定会用到的&lt;/p&gt;

&lt;p&gt;创建 add_mati_to_admin_sidebar.rb 文件&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Deface&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Override&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="ss"&gt;virtual_path: &lt;/span&gt;&lt;span class="s1"&gt;'spree/admin/shared/_main_menu'&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;'mati_admin_sidebar_menu'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="ss"&gt;insert_top: &lt;/span&gt;&lt;span class="s1"&gt;'nav'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="ss"&gt;partial: &lt;/span&gt;&lt;span class="s1"&gt;'spree/admin/shared/mati_sidebar_menu'&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;mati_sidebar_menu 在 app/views/spree/admin/shared/目录下&lt;/p&gt;

&lt;p&gt;mati_sidebar_menu.html.erb&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="sx"&gt;% if &lt;/span&gt;&lt;span class="n"&gt;can?&lt;/span&gt; &lt;span class="ss"&gt;:admin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Spree&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Mati&lt;/span&gt; &lt;span class="sx"&gt;%&amp;gt;
    &amp;lt;ul class="nav nav-sidebar border-bottom"&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sx"&gt;%= main_menu_tree Spree.t(:mati), icon: "leaf", sub_menu: "mati", url: "#sidebar-mati" %&amp;gt;
    &amp;lt;/ul&amp;gt;
  &amp;lt;% end %&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后在 shared/sub_menu/_mati.html.erb&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;ul&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"sidebar-mati"&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"border-top bg-white collapse nav nav-pills nav-stacked"&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;hook&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"admin_mati_sub_tabs"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sx"&gt;%= tab :mati_imports %&amp;gt;
&amp;lt;%=&lt;/span&gt; &lt;span class="n"&gt;configurations_sidebar_menu_item&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Spree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;t&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'mati_settings.title'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;admin_mati_settings_path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;can?&lt;/span&gt; &lt;span class="ss"&gt;:manage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Spree&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;MatiSetting&lt;/span&gt; &lt;span class="sx"&gt;%&amp;gt;
&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这样一个导航菜单就完成了，包含两个导航，一个链接到 imoprts 页面，一个链接到设置页面，这里 Spree::MatiSetting 是第二步里创建的模型&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5、添加控制器 controller&lt;/strong&gt;
我们只有一个导入功能和一个设置，因此只有两个控制器就可以了&lt;/p&gt;

&lt;p&gt;分别是 mati_imports_controller.rb 和 mati_settings_controller.rb 具体内容查看我的代码，这边不详细写了。mati_imports_controller 除了 index 方法我们还定义了 importdata 用来导入对应表格的产品数据&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6、添加自己的辅助方法 helpers 和服务代码&lt;/strong&gt;
在 app/helpers/目录下创建 products_helper_decorator.rb &lt;/p&gt;

&lt;p&gt;重写了 product_description 方法和添加了 product_bullet_point 方法用来修正前台产品页显示 description 和 bullet_point 方式，可以在 view 页面里直接使用&lt;/p&gt;

&lt;p&gt;创建 app/services 文件目录，这个目录下的代码我称为服务代码，可以在控制器里直接使用&lt;/p&gt;

&lt;p&gt;我们创建了 albums_service.rb ,color_code.rb,import_service.rb, size_code.rb, template_seed.rb&lt;/p&gt;

&lt;p&gt;albums_service.rb 是处理导入文件用到的一些方法，这里都采用类方法的形式，不需要实例化直接使用&lt;/p&gt;

&lt;p&gt;比如这个 获取表格标题的方法&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_title_of_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sheet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;slipstr&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;)&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;这个方法在控制器直接用 AlbumsService.get_title_of_template 就可以调用了。&lt;/p&gt;

&lt;p&gt;color_code.rb 是处理颜色的代码，我们约定了颜色的缩写，在我的另一个 erp 系统里，根据图片名称包含的颜色代码缩写，自动生产 sku，和产品颜色的功能，这边引导入产品表格有包含 sku 和颜色，所以暂时没什么用。保留以后可以使用。&lt;/p&gt;

&lt;p&gt;import _service.rb 来自 spree 的原版 代码，做些修改，使其可以导入图片和设置库存之类的功能。&lt;/p&gt;

&lt;p&gt;size_code.rb 类似 color_code.rb 处理尺码的代码&lt;/p&gt;

&lt;p&gt;TemplateSeed 我们定义了一些常量，用来存储亚马逊表格常用字段。这里可以帮它设置到数据库里面比如，在 Spree::MatiSetting 模型 文件里。我们这边没这么做是因为这个基本是固定的，所以我们设置为常量&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7、添加修改视图 views&lt;/strong&gt;
在 app/views/spree/admin/目录下创建&lt;/p&gt;

&lt;p&gt;mati_imports 和 mati_setting 文件目录，里面放对应的视图文件&lt;/p&gt;

&lt;p&gt;比如 mati_imports 里面有 index.html.erb 和_form.html.erb。mati_setting 里有 edit.html.erb 文件。&lt;/p&gt;

&lt;p&gt;在 app/veiws/spree/products/ 目录下添加产品展示页面新增的两个字段 amazon_link 和 bullet_point&lt;/p&gt;

&lt;p&gt;我们来看下具体怎么写。比如_amazon_link.html.erb&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="sx"&gt;% if &lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="vi"&gt;@product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;amazon_link&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;blank?&lt;/span&gt; &lt;span class="sx"&gt;%&amp;gt;
&amp;lt;div id="amazon-link" class="mt-2"  data-hook="amazon-link"&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sx"&gt;%= link_to @product.amazon_link , class: 'btn btn-warning btn-block' do %&amp;gt;
  &amp;lt;%=&lt;/span&gt;&lt;span class="vi"&gt;@product.amazon_title&lt;/span&gt;&lt;span class="o"&gt;%&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Now&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sx"&gt;% end &lt;/span&gt;&lt;span class="o"&gt;%&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sx"&gt;% end &lt;/span&gt;&lt;span class="o"&gt;%&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;上面我们提到的第 4 步，override 文件下我们创建了&lt;/p&gt;

&lt;p&gt;add_amazon_link_to_product_show.rb 就是用来调用这个 view 文件的具体看 里面的内容&lt;/p&gt;

&lt;p&gt;app/overrides/spree/admin/add_amazon_link_to_product_show.rb&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Deface&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Override&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="ss"&gt;virtual_path: &lt;/span&gt;&lt;span class="s1"&gt;'spree/products/show'&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;'Add amazon links to show'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="ss"&gt;insert_after: &lt;/span&gt;&lt;span class="s1"&gt;'div[data-hook="cart_form"]'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="ss"&gt;partial: &lt;/span&gt;&lt;span class="s1"&gt;'spree/products/amazon_link'&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;非常简单&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;8、修改引擎文件，设置配置启动文件和版本的控制&lt;/strong&gt;
lib/spree_mati/engine.rb 就是引擎文件默认不需修改，我们这边要让程序载入配置文件，因此我们增加了下面代码；&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;initializer&lt;/span&gt; &lt;span class="s1"&gt;'spree.mati.environment'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;before: :load_config_initializers&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;_app&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="no"&gt;Spree&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;MatiConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Spree&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;MatiSetting&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这样可以直接在控制器，视图等地方直接使用 Spree::MatiConfig 来获取配置字段。比如&lt;/p&gt;

&lt;p&gt;Spree::MatiConfig.import_row_from_title 就可以获取我们的设置字段了。&lt;/p&gt;

&lt;p&gt;版本控制，你做一次修改后，在版本文件 lib/spree_mati/version.rb 修改版本数字，一般是小修改，比如 TINY  = 1 这里改为 2 就好了，每次加 1 就好了。具体看你喜欢但是一定要重小到大。&lt;/p&gt;

&lt;p&gt;因为项目比较简单，我并没有写测试，测试可以在写控制器 辅助方法和 views 的时候逐步完成。&lt;/p&gt;

&lt;p&gt;最后在主程序安装我们插件的时候别忘了加入&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;'roo'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'~&amp;gt; 2.8.0'&lt;/span&gt;
&lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;'roo-xls'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;不然会无法调用 roo 的。&lt;/p&gt;

&lt;p&gt;这里是你使用 spree 时要添加的 gem：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;'spree'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'~&amp;gt; 4.1'&lt;/span&gt;
&lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;'spree_auth_devise'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'~&amp;gt; 4.1'&lt;/span&gt;
&lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;'spree_gateway'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'~&amp;gt; 3.7'&lt;/span&gt;
&lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;'spree_mati'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;github: &lt;/span&gt;&lt;span class="s1"&gt;'TCnet/spree_mati'&lt;/span&gt;
&lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;'roo'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'~&amp;gt; 2.8.0'&lt;/span&gt;
&lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;'roo-xls'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;以上 8 个步骤是我总结的 spree 插件开发的过程。&lt;/p&gt;

&lt;p&gt;可以帮助初学者尽快写出一个自己的 spree 插件。&lt;/p&gt;</description>
      <author>TCnet</author>
      <pubDate>Mon, 20 Apr 2020 18:08:37 +0800</pubDate>
      <link>https://ruby-china.org/topics/39765</link>
      <guid>https://ruby-china.org/topics/39765</guid>
    </item>
    <item>
      <title>如何在 Ubuntu 16.04 LTS 服务器上安装 Node.js</title>
      <description>&lt;p&gt;第一次部署 rails 6 项目，踩了很多坑。经过各种 google 搜索总算成功了。
其中需要安装 nodejs 让我找了不少时间，这边写一篇日志记录下，希望对大家有用。
第一次发文章，有点小激动（ps 以前只看不发。。）&lt;/p&gt;

&lt;p&gt;正题：&lt;/p&gt;

&lt;p&gt;在这个系统 ubuntu 16.04  不能直接命令安装 node。这个原因，可以去 node 官网查询。
需要采用 nodesource 安装。可以参考 &lt;a href="https://github.com/nodesource/distributions/blob/master/README.md" rel="nofollow" target="_blank"&gt;https://github.com/nodesource/distributions/blob/master/README.md&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;具体分 5 部：&lt;/p&gt;

&lt;p&gt;1、删除旧版 默认系统安装了 node 4.2.6 这个要删除 不然存在两个版本导致部署失败。
进入服务器终端&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get purge &lt;span class="nt"&gt;--auto-remove&lt;/span&gt; nodejs
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2、添加 NodeSource package signing key
在服务器终端&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-sSL&lt;/span&gt; https://deb.nodesource.com/gpgkey/nodesource.gpg.key | &lt;span class="nb"&gt;sudo &lt;/span&gt;apt-key add -
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;3、在服务器终端，直接逐行输入下面 4 行&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;VERSION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;node_10.x
&lt;span class="nv"&gt;DISTRO&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;lsb_release &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"deb https://deb.nodesource.com/&lt;/span&gt;&lt;span class="nv"&gt;$VERSION&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$DISTRO&lt;/span&gt;&lt;span class="s2"&gt; main"&lt;/span&gt; | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; /etc/apt/sources.list.d/nodesource.list
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"deb-src https://deb.nodesource.com/&lt;/span&gt;&lt;span class="nv"&gt;$VERSION&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$DISTRO&lt;/span&gt;&lt;span class="s2"&gt; main"&lt;/span&gt; | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; &lt;span class="nt"&gt;-a&lt;/span&gt; /etc/apt/sources.list.d/nodesource.list
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;VERSION=node_10.x 这里 10 可以替换需要的版本比如 8 9 等
4、接下去就可以安装 node 了&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install &lt;/span&gt;nodejs

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;5、yarn 也可以安装了。&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;yarn &lt;span class="nt"&gt;-g&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;好了完成了。
查看 node 版本&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node &lt;span class="nt"&gt;-v&lt;/span&gt;
npm &lt;span class="nt"&gt;-v&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;</description>
      <author>TCnet</author>
      <pubDate>Wed, 16 Oct 2019 20:15:10 +0800</pubDate>
      <link>https://ruby-china.org/topics/39160</link>
      <guid>https://ruby-china.org/topics/39160</guid>
    </item>
    <item>
      <title>服务器配置 Rails 程序的错误 求解</title>
      <description>&lt;p&gt;这个是日志最后几十行。
访问网址 提示拒绝访问。&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="ss"&gt;bundler: &lt;/span&gt;&lt;span class="n"&gt;failed&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="nb"&gt;load&lt;/span&gt; &lt;span class="ss"&gt;command: &lt;/span&gt;&lt;span class="n"&gt;unicorn&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/home/&lt;/span&gt;&lt;span class="n"&gt;deploy&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;apps&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;zebra_production&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;shared&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bundle&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;ruby&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;2.3&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bin&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;unicorn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;ArgumentError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Already&lt;/span&gt; &lt;span class="n"&gt;running&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt; &lt;span class="no"&gt;PID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;4327&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sr"&gt;/home/&lt;/span&gt;&lt;span class="n"&gt;deploy&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;apps&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;zebra_production&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;current&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;pids&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;unicorn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pid&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;stale&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="sr"&gt;/home/&lt;/span&gt;&lt;span class="n"&gt;deploy&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;apps&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;zebra_production&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;shared&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bundle&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;ruby&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;2.3&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;gems&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;unicorn&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;4.8&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;unicorn&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;http_server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;206&lt;/span&gt;&lt;span class="ss"&gt;:in&lt;/span&gt; &lt;span class="sb"&gt;`pid='
  /home/deploy/apps/zebra_production/shared/bundle/ruby/2.3.0/gems/unicorn-4.8.3/lib/unicorn/http_server.rb:135:in `&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="s1"&gt;'
  /home/deploy/apps/zebra_production/shared/bundle/ruby/2.3.0/gems/unicorn-4.8.3/bin/unicorn:126:in `&amp;lt;top (required)&amp;gt;'&lt;/span&gt;
  &lt;span class="sr"&gt;/home/&lt;/span&gt;&lt;span class="n"&gt;deploy&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;apps&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;zebra_production&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;shared&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bundle&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;ruby&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;2.3&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bin&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;unicorn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;23&lt;/span&gt;&lt;span class="ss"&gt;:in&lt;/span&gt; &lt;span class="sb"&gt;`load'
  /home/deploy/apps/zebra_production/shared/bundle/ruby/2.3.0/bin/unicorn:23:in `&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;top&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;required&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="s1"&gt;'
I, [2017-05-17T01:47:54.005704 #4383]  INFO -- : executing ["/home/deploy/apps/zebra_production/shared/bundle/ruby/2.3.0/bin/unicorn", "-D", "-c", "/home/deploy/apps/zebra_production/shared/config/unicorn.rb", "-E", "production", {12=&amp;gt;#&amp;lt;Kgio::UNIXServer:/tmp/unicorn.zebra_production.sock&amp;gt;}] (in /home/deploy/apps/zebra_production/releases/20170516134056)
I, [2017-05-17T01:47:54.347907 #4383]  INFO -- : inherited addr=/tmp/unicorn.zebra_production.sock fd=12
I, [2017-05-17T01:47:54.348308 #4383]  INFO -- : Refreshing Gem list
We'&lt;/span&gt;&lt;span class="n"&gt;ve&lt;/span&gt; &lt;span class="n"&gt;got&lt;/span&gt; &lt;span class="n"&gt;an&lt;/span&gt; &lt;span class="n"&gt;old&lt;/span&gt; &lt;span class="n"&gt;pid&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="n"&gt;pid&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;old&lt;/span&gt; &lt;span class="n"&gt;pid&lt;/span&gt;
&lt;span class="n"&gt;killing&lt;/span&gt; &lt;span class="n"&gt;master&lt;/span&gt; &lt;span class="n"&gt;process&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;good&lt;/span&gt; &lt;span class="n"&gt;thing&lt;/span&gt; &lt;span class="n"&gt;tm&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;We&lt;/span&gt;&lt;span class="s1"&gt;'ve got an old pid and server pid is not the old pid
killing master process (good thing tm)
We'&lt;/span&gt;&lt;span class="n"&gt;ve&lt;/span&gt; &lt;span class="n"&gt;got&lt;/span&gt; &lt;span class="n"&gt;an&lt;/span&gt; &lt;span class="n"&gt;old&lt;/span&gt; &lt;span class="n"&gt;pid&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="n"&gt;pid&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;old&lt;/span&gt; &lt;span class="n"&gt;pid&lt;/span&gt;
&lt;span class="no"&gt;I&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2017&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mo"&gt;05&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;17&lt;/span&gt;&lt;span class="no"&gt;T01&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;47&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;56.846945&lt;/span&gt; &lt;span class="c1"&gt;#4388]  INFO -- : worker=0 ready&lt;/span&gt;
&lt;span class="n"&gt;killing&lt;/span&gt; &lt;span class="n"&gt;master&lt;/span&gt; &lt;span class="n"&gt;process&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;good&lt;/span&gt; &lt;span class="n"&gt;thing&lt;/span&gt; &lt;span class="n"&gt;tm&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;We&lt;/span&gt;&lt;span class="s1"&gt;'ve got an old pid and server pid is not the old pid
killing master process (good thing tm)
We'&lt;/span&gt;&lt;span class="n"&gt;ve&lt;/span&gt; &lt;span class="n"&gt;got&lt;/span&gt; &lt;span class="n"&gt;an&lt;/span&gt; &lt;span class="n"&gt;old&lt;/span&gt; &lt;span class="n"&gt;pid&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="n"&gt;pid&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;old&lt;/span&gt; &lt;span class="n"&gt;pid&lt;/span&gt;
&lt;span class="n"&gt;killing&lt;/span&gt; &lt;span class="n"&gt;master&lt;/span&gt; &lt;span class="n"&gt;process&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;good&lt;/span&gt; &lt;span class="n"&gt;thing&lt;/span&gt; &lt;span class="n"&gt;tm&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;I&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2017&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mo"&gt;05&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;17&lt;/span&gt;&lt;span class="no"&gt;T01&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;47&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;56.881755&lt;/span&gt; &lt;span class="c1"&gt;#4392]  INFO -- : worker=1 ready&lt;/span&gt;
&lt;span class="no"&gt;I&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2017&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mo"&gt;05&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;17&lt;/span&gt;&lt;span class="no"&gt;T01&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;47&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;56.886841&lt;/span&gt; &lt;span class="c1"&gt;#4396]  INFO -- : worker=2 ready&lt;/span&gt;
&lt;span class="no"&gt;I&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2017&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mo"&gt;05&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;17&lt;/span&gt;&lt;span class="no"&gt;T01&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;47&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;56.889503&lt;/span&gt; &lt;span class="c1"&gt;#4383]  INFO -- : master process ready&lt;/span&gt;
&lt;span class="no"&gt;I&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2017&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mo"&gt;05&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;17&lt;/span&gt;&lt;span class="no"&gt;T01&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;47&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;56.916412&lt;/span&gt; &lt;span class="c1"&gt;#4400]  INFO -- : worker=3 ready&lt;/span&gt;
&lt;span class="no"&gt;I&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2017&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mo"&gt;05&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;17&lt;/span&gt;&lt;span class="no"&gt;T01&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;47&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;56.926179&lt;/span&gt; &lt;span class="c1"&gt;#4404]  INFO -- : worker=4 ready&lt;/span&gt;
&lt;span class="no"&gt;I&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2017&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mo"&gt;05&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;17&lt;/span&gt;&lt;span class="no"&gt;T01&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;47&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;57.606026&lt;/span&gt; &lt;span class="c1"&gt;#4327]  INFO -- : reaped #&amp;lt;Process::Status: pid 4331 exit 0&amp;gt; worker=0&lt;/span&gt;
&lt;span class="no"&gt;I&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2017&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mo"&gt;05&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;17&lt;/span&gt;&lt;span class="no"&gt;T01&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;47&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;57.606243&lt;/span&gt; &lt;span class="c1"&gt;#4327]  INFO -- : reaped #&amp;lt;Process::Status: pid 4333 exit 0&amp;gt; worker=1&lt;/span&gt;
&lt;span class="no"&gt;I&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2017&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mo"&gt;05&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;17&lt;/span&gt;&lt;span class="no"&gt;T01&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;47&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;57.606299&lt;/span&gt; &lt;span class="c1"&gt;#4327]  INFO -- : reaped #&amp;lt;Process::Status: pid 4337 exit 0&amp;gt; worker=2&lt;/span&gt;
&lt;span class="no"&gt;I&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2017&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mo"&gt;05&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;17&lt;/span&gt;&lt;span class="no"&gt;T01&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;47&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;57.606349&lt;/span&gt; &lt;span class="c1"&gt;#4327]  INFO -- : reaped #&amp;lt;Process::Status: pid 4341 exit 0&amp;gt; worker=3&lt;/span&gt;
&lt;span class="no"&gt;I&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2017&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mo"&gt;05&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;17&lt;/span&gt;&lt;span class="no"&gt;T01&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;47&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;57.606396&lt;/span&gt; &lt;span class="c1"&gt;#4327]  INFO -- : reaped #&amp;lt;Process::Status: pid 4345 exit 0&amp;gt; worker=4&lt;/span&gt;
&lt;span class="no"&gt;I&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2017&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mo"&gt;05&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;17&lt;/span&gt;&lt;span class="no"&gt;T01&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;47&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;57.606442&lt;/span&gt; &lt;span class="c1"&gt;#4327]  INFO -- : master complete&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;</description>
      <author>TCnet</author>
      <pubDate>Wed, 17 May 2017 09:56:09 +0800</pubDate>
      <link>https://ruby-china.org/topics/33005</link>
      <guid>https://ruby-china.org/topics/33005</guid>
    </item>
  </channel>
</rss>
