<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>wfwdex (wfwdex)</title>
    <link>https://ruby-china.org/wfwdex</link>
    <description></description>
    <language>en-us</language>
    <item>
      <title>服务器负载过高怎样优化？</title>
      <description>&lt;p&gt;目前应用的情况如下：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;API 接口每天要接受大约 1.4 亿次请求&lt;/li&gt;
&lt;li&gt;目前 web 服务器由三台 8 核 16GB 的服务器做负载均衡&lt;/li&gt;
&lt;li&gt;mysql 数据库放在 8 核 16GB 的单台服务器上&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;目前 web 服务器的负载一直维持 1 以上，如目前：&lt;code&gt;Load average: 1.46 1.07 1.06&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;puma 配置：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;workers 8
threads 16,32
&lt;/code&gt;&lt;/pre&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Linux 4.4.0-109-generic (ruby1)     03/07/2018  _x86_64_    (8 CPU)

08:08:00 AM     CPU     %user     %nice   %system   %iowait    %steal     %idle
08:08:01 AM     all     26.99      0.00      5.67      0.00      0.00     67.34
08:08:02 AM     all     22.92      0.00      4.41      0.00      0.00     72.67
08:08:03 AM     all     15.17      0.00      2.40      0.00      0.00     82.43
08:08:04 AM     all     20.65      0.00      3.78      0.00      0.00     75.57
08:08:05 AM     all      9.34      0.00      2.02      0.13      0.00     88.51
08:08:06 AM     all     10.37      0.00      1.77      0.00      0.00     87.86
08:08:07 AM     all     10.81      0.00      1.65      0.00      0.00     87.53
08:08:08 AM     all      7.38      0.00      2.75      0.00      0.00     89.88
08:08:09 AM     all      8.35      0.00      1.87      0.00      0.00     89.78
08:08:10 AM     all      9.80      0.00      1.63      0.00      0.00     88.57
08:08:11 AM     all      9.42      0.00      1.63      0.00      0.00     88.94
08:08:12 AM     all      8.59      0.00      1.26      0.00      0.00     90.15
08:08:13 AM     all     12.61      0.00      2.52      0.00      0.00     84.87
08:08:14 AM     all     18.72      0.00      3.14      0.00      0.00     78.14
08:08:15 AM     all      9.71      0.00      1.26      0.00      0.00     89.03
08:08:16 AM     all      8.79      0.00      1.88      0.00      0.00     89.32
08:08:17 AM     all     10.43      0.00      1.13      0.00      0.00     88.44
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;API 已经做过缓存优化，请问这种情况除了继续加服务器，还有没有其他优化思路和方向？&lt;/p&gt;</description>
      <author>wfwdex</author>
      <pubDate>Wed, 07 Mar 2018 08:22:51 +0800</pubDate>
      <link>https://ruby-china.org/topics/35184</link>
      <guid>https://ruby-china.org/topics/35184</guid>
    </item>
    <item>
      <title>利用位运算在一个字段存多个属性值有什么弊端？</title>
      <description>&lt;p&gt;晚上看到一个 gem, bit_settings,  &lt;a href="https://github.com/pioz/bit_settings/blob/master/lib/bit_settings.rb" rel="nofollow" target="_blank" title=""&gt;文件&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;def&lt;/span&gt; &lt;span class="nf"&gt;add_settings&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;:,&lt;/span&gt; &lt;span class="ss"&gt;column: :settings&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;prefix: &lt;/span&gt;&lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;prefix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;prefix&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;prefix&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="s1"&gt;''&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;size&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="s1"&gt;'You can NOT have more than 32 settings (max unsigned int with 4 bytes is 2^32-1)'&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each_with_index&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;setting&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;define_method&lt;/span&gt; &lt;span class="s2"&gt;"&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="n"&gt;setting&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&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="mi"&gt;0&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="kp"&gt;alias_method&lt;/span&gt; &lt;span class="s2"&gt;"&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="n"&gt;setting&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;?"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;prefix&lt;/span&gt;&lt;span class="si"&gt;}#{&lt;/span&gt;&lt;span class="n"&gt;setting&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
      &lt;span class="n"&gt;define_method&lt;/span&gt; &lt;span class="s2"&gt;"&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="n"&gt;setting&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;="&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="no"&gt;ActiveModel&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Boolean&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="nf"&gt;cast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&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;column&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;="&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;column&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="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;
          &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&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;column&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;="&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这个 gem 主要实现在一个字段存多个（最大 32 个）bool 型的属性。&lt;/p&gt;

&lt;p&gt;这样做看起来很酷，想知道如果在现实的项目中这样用，有没有什么弊端？或者不方便的地方？&lt;/p&gt;

&lt;p&gt;我能想到有一个场景不方便，比如按指定的多个属性做 group by 操作。&lt;/p&gt;</description>
      <author>wfwdex</author>
      <pubDate>Fri, 17 Nov 2017 21:25:17 +0800</pubDate>
      <link>https://ruby-china.org/topics/34589</link>
      <guid>https://ruby-china.org/topics/34589</guid>
    </item>
    <item>
      <title>关于将 ActiveRecord 结果集缓存到 Redis 的 HASH 中</title>
      <description>&lt;p&gt;在优化项目响应时，想将 ActiveRecord 的结果集存在 Redis 的 HASH 中，主要是为了好管理。&lt;/p&gt;

&lt;p&gt;比如用关联的 user_id 当做 HASH 的 key:&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;books&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;user_id: &lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="vg"&gt;$redis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"books"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;books&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_json&lt;/span&gt;&lt;span class="p"&gt;)&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="n"&gt;books&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vg"&gt;$redis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"books"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这样做的问题是取出时并不会还原成 ActiveRecord 结果集对象，而且数据量大的时候不知道会不会有性能问题。&lt;/p&gt;

&lt;p&gt;但是使用&lt;code&gt;Rails.cache.write&lt;/code&gt;又不支持存进 Redis 的 HASH 中，请教一下有没有更好的方法解决这个问题？&lt;/p&gt;</description>
      <author>wfwdex</author>
      <pubDate>Wed, 25 Oct 2017 19:33:51 +0800</pubDate>
      <link>https://ruby-china.org/topics/34428</link>
      <guid>https://ruby-china.org/topics/34428</guid>
    </item>
    <item>
      <title>一台独立的 ELK日志服务器，如果通过 Beats 收集另一台 Rails Web 服务器上的日志？</title>
      <description>&lt;p&gt;ELK 指的是 elasticsearch/logstash/kibana&lt;/p&gt;

&lt;p&gt;目前是用 socat 配合 tail，通过 udp 往日志服务器直接发送给 logstash，请问最好的方式是什么？&lt;/p&gt;</description>
      <author>wfwdex</author>
      <pubDate>Wed, 18 Oct 2017 09:06:14 +0800</pubDate>
      <link>https://ruby-china.org/topics/34395</link>
      <guid>https://ruby-china.org/topics/34395</guid>
    </item>
    <item>
      <title>关于如何避免客户端同一时间提交重复请求的问题</title>
      <description>&lt;p&gt;我遇到的问题如下：&lt;/p&gt;

&lt;p&gt;iOS 客户端因为第一次打开应用需要用户允许&lt;code&gt;网络访问权限&lt;/code&gt;，导致第一次发送请求（用于分配帐号）总是在同一时间（1 秒钟内）重复发送多次（2-3 次）。&lt;/p&gt;

&lt;p&gt;这样就导致服务端会为这个 uuid 的设备创建多个分配帐号，虽然产品逻辑上是允许一个 uuid 通过另一个注册接口去注册多个帐号，但是并不允许在第一次打开 app 的时候分配多个帐号，所以就导致我无法通过为 uuid 创建数据库约束来避免这种情况。&lt;/p&gt;

&lt;p&gt;请问如果不从客户端下手，API 后端如何避免让一个 uuid 在 1 秒钟内同时创建多个帐号？&lt;/p&gt;

&lt;hr&gt;

&lt;p&gt;在写完这个帖子后，我想到一个办法，就是为&lt;code&gt;uuid&lt;/code&gt;和&lt;code&gt;created_at&lt;/code&gt;创建联合唯一约束，本着深入研究的精神，想请求除了这个还有别的更好办法吗？&lt;/p&gt;</description>
      <author>wfwdex</author>
      <pubDate>Mon, 31 Jul 2017 14:03:55 +0800</pubDate>
      <link>https://ruby-china.org/topics/33673</link>
      <guid>https://ruby-china.org/topics/33673</guid>
    </item>
    <item>
      <title>怎样让 Rails 的 params 根据请求来获取对应类型的参数？</title>
      <description>&lt;p&gt;比如我的接口是&lt;code&gt;POST&lt;/code&gt;类型，我只想让客户端发起请求传参时使用&lt;code&gt;Form Data&lt;/code&gt;，不接受从 URL 传来的参数。&lt;/p&gt;

&lt;p&gt;现在很多客户端同事不知道这个问题，把&lt;code&gt;POST&lt;/code&gt;请求的参数全部通过 URL 传到后端，而 Rails 里使用 params 又能正常获取 URL 传来的参数。&lt;/p&gt;

&lt;p&gt;问题是：Rails 如何优雅地只允许获取 &lt;code&gt;Form Data&lt;/code&gt; 或 &lt;code&gt;URL&lt;/code&gt; 传来的参数？&lt;/p&gt;

&lt;hr&gt;

&lt;p&gt;今天发现用 json 发到后端的请求都会被正常解析到 params 里，本来参数值应该是字符型，但由于 json 支持 integer，导致前端使用了 integer，引发了 bug。&lt;/p&gt;</description>
      <author>wfwdex</author>
      <pubDate>Fri, 28 Jul 2017 11:43:07 +0800</pubDate>
      <link>https://ruby-china.org/topics/33657</link>
      <guid>https://ruby-china.org/topics/33657</guid>
    </item>
    <item>
      <title>Phoenix vs Rails: quick performance comparison 被最后的 ab 压测震惊了</title>
      <description>&lt;p&gt;&lt;span class="embed-responsive embed-responsive-16by9"&gt;&lt;iframe class="embed-responsive-item" src="//www.youtube.com/embed/G39iAUHh2e8" allowfullscreen=""&gt;&lt;/iframe&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;这几天在想办法优化自己参与的项目，无意中看到这个视频。&lt;/p&gt;

&lt;p&gt;最后的压测差距好多，不知道在完整的项目中差距是不是这么大。&lt;/p&gt;</description>
      <author>wfwdex</author>
      <pubDate>Sat, 01 Jul 2017 00:56:01 +0800</pubDate>
      <link>https://ruby-china.org/topics/33372</link>
      <guid>https://ruby-china.org/topics/33372</guid>
    </item>
    <item>
      <title>怎样实现整数定时任务？</title>
      <description>&lt;p&gt;比如我需要实现一天里每 10 分钟整数时执行的定时任务&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;00:10, 00:20, 00:30, 00: 40, 00:50, 01:00 ...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;类似上面这样，每整数 10 分钟时执行一次。&lt;/p&gt;

&lt;p&gt;请救一下大家有没有可行的方案？&lt;/p&gt;</description>
      <author>wfwdex</author>
      <pubDate>Fri, 30 Jun 2017 16:05:28 +0800</pubDate>
      <link>https://ruby-china.org/topics/33366</link>
      <guid>https://ruby-china.org/topics/33366</guid>
    </item>
    <item>
      <title>怎样提高一个写入数据非常频繁的 API 接口的并发处理性能?</title>
      <description>&lt;p&gt;目前项目里有一个日志接口写入非常频繁，目前自己做过 AB 压力测试，在请求数为 10000，并发数为 100 的情况下，Requests per second 只能达到 36/s，期望能达到 100/s 以上。&lt;/p&gt;

&lt;p&gt;这种情况下如果把这个接口的请求送入队列，比如 sidekiq，然后用队列的多线程去写入是不是一个可行的方案？有没有什么弊端？&lt;/p&gt;

&lt;p&gt;或者有没有更好的方法去优化？&lt;/p&gt;</description>
      <author>wfwdex</author>
      <pubDate>Fri, 30 Jun 2017 09:18:29 +0800</pubDate>
      <link>https://ruby-china.org/topics/33362</link>
      <guid>https://ruby-china.org/topics/33362</guid>
    </item>
    <item>
      <title>使用 Kaminari 分页时，遇到使用 distinct 的语句，分页会不准确</title>
      <description>&lt;p&gt;使用 kaminari 对去重的语句进行分页时，生成的分页语句有问题：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;logs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;OperationLog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:user_id&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;interface_id: &lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:interface_id&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;page&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;param_page&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;per&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;param_limit&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;distinct&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;生成的语句&lt;/p&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- 分页语句&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt;  &lt;span class="k"&gt;DISTINCT&lt;/span&gt; &lt;span class="nv"&gt;`operation_logs`&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;`user_id`&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="nv"&gt;`operation_logs`&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="nv"&gt;`operation_logs`&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;`interface_id`&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt; &lt;span class="k"&gt;OFFSET&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="c1"&gt;-- 查询关联用户&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="nv"&gt;`users`&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="nv"&gt;`users`&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="nv"&gt;`users`&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;`id`&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;150&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;175&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;126&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;133&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;124&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;-- 获取总记录数&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;DISTINCT&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;DISTINCT&lt;/span&gt; &lt;span class="nv"&gt;`operation_logs`&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;`id`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="nv"&gt;`operation_logs`&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="nv"&gt;`operation_logs`&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;`interface_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;事实上总记录数并没有按 DISTINCT 指定的字段去重，导致总记录数是未去重的数量，&lt;/p&gt;

&lt;p&gt;查了 kaminari 项目 README.md 和 google，都没找到解决方法，目前使用的是 Kaminari.paginate_array，对总结果分页，这样显然是不对的，记录数多了之后，性能有很大问题。&lt;/p&gt;

&lt;p&gt;请问这个问题怎么解决？&lt;/p&gt;</description>
      <author>wfwdex</author>
      <pubDate>Wed, 31 May 2017 20:33:57 +0800</pubDate>
      <link>https://ruby-china.org/topics/33106</link>
      <guid>https://ruby-china.org/topics/33106</guid>
    </item>
    <item>
      <title>怎样让 Vim 在 visual 模式选中一段文字粘贴时，不将选中的文字替换到剪贴板？</title>
      <description>&lt;p&gt;在 visual 模式下，我首先复制或剪切了一段文字，我想粘贴的方式替换文件中两处文字。&lt;/p&gt;

&lt;p&gt;当我选中要替换的文字，按下 p 键粘贴时，选中的文字就会替换我在剪贴板里复制的文字。&lt;/p&gt;

&lt;p&gt;搞得我又要重新回去复制那段文字。&lt;/p&gt;

&lt;p&gt;请问怎样在我选中文字并按下 p 键时，避免选中的文字替换我的剪贴板内容？&lt;/p&gt;

&lt;p&gt;最好是能直接修改设置，而不是让我抛弃使用现有的默认快捷键。&lt;/p&gt;</description>
      <author>wfwdex</author>
      <pubDate>Wed, 24 May 2017 08:35:19 +0800</pubDate>
      <link>https://ruby-china.org/topics/33052</link>
      <guid>https://ruby-china.org/topics/33052</guid>
    </item>
    <item>
      <title>[求助] 关于 Rails 中奇怪的时区问题</title>
      <description>&lt;p&gt;前提是我在&lt;code&gt;application.rb&lt;/code&gt;中已经加入了：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;time_zone&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Beijing'&lt;/span&gt;
&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;active_record&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;default_timezone&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;:local&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我在 rails console 中查询用户的登录日志，返回的创建时间是： &lt;code&gt;2017-05-10 15:13:10&lt;/code&gt;&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;irb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="mo"&gt;001&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;&amp;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;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;user_signin_logs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;order&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;created_at: :desc&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;
  &lt;span class="no"&gt;User&lt;/span&gt; &lt;span class="no"&gt;Load&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.4&lt;/span&gt;&lt;span class="n"&gt;ms&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="no"&gt;SELECT&lt;/span&gt;  &lt;span class="sb"&gt;`users`&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;*&lt;/span&gt; &lt;span class="no"&gt;FROM&lt;/span&gt; &lt;span class="sb"&gt;`users`&lt;/span&gt; &lt;span class="no"&gt;WHERE&lt;/span&gt; &lt;span class="sb"&gt;`users`&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;`&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="sb"&gt;` = 2 LIMIT 1
  UserSigninLog Load (0.6ms)  SELECT  `&lt;/span&gt;&lt;span class="n"&gt;user_signin_logs&lt;/span&gt;&lt;span class="sb"&gt;`.* FROM `&lt;/span&gt;&lt;span class="n"&gt;user_signin_logs&lt;/span&gt;&lt;span class="sb"&gt;` WHERE `&lt;/span&gt;&lt;span class="n"&gt;user_signin_logs&lt;/span&gt;&lt;span class="sb"&gt;`.`&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="sb"&gt;` = 2 ORDER BY `&lt;/span&gt;&lt;span class="n"&gt;user_signin_logs&lt;/span&gt;&lt;span class="sb"&gt;`.`&lt;/span&gt;&lt;span class="n"&gt;created_at&lt;/span&gt;&lt;span class="sb"&gt;` DESC LIMIT 1
=&amp;gt; #&amp;lt;UserSigninLog id: "2e20a942-3593-11e7-8338-00163e01107f", user_id: 2, ip: "27.17.98.36", ip_country: "中国", ip_province: "湖北", ip_city: "武汉", created_at: "2017-05-10 15:13:10", updated_at: "2017-05-10 15:13:10"&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我用同样的 sql 语句直接去查数据库，得到的结果却是：&lt;code&gt;2017-05-10 23:13:10&lt;/code&gt;&lt;/p&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;mysql&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;SELECT&lt;/span&gt;  &lt;span class="nv"&gt;`user_signin_logs`&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="nv"&gt;`user_signin_logs`&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="nv"&gt;`user_signin_logs`&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;`user_id`&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="nv"&gt;`user_signin_logs`&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;`created_at`&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt; &lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="c1"&gt;--------------------------------------+---------+------------+-------------+-----------+--------------+---------------------+---------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;                                   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;ip&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;ip_country&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;ip_province&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;ip_city&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;created_at&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;updated_at&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="c1"&gt;--------------------------------------+---------+------------+-------------+-----------+--------------+---------------------+---------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;e20a942&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;3593&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="n"&gt;e7&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;8338&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;00163&lt;/span&gt;&lt;span class="n"&gt;e01107f&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="mi"&gt;2&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="err"&gt;中国&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="err"&gt;湖北&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="err"&gt;武汉&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="mi"&gt;2017&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;05&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="mi"&gt;23&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;2017&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;05&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="mi"&gt;23&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="c1"&gt;--------------------------------------+---------+------------+-------------+-----------+--------------+---------------------+---------------------+&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;row&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;02&lt;/span&gt; &lt;span class="n"&gt;sec&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;看了 &lt;a href="/boyishwei" class="user-mention" title="@boyishwei"&gt;&lt;i&gt;@&lt;/i&gt;boyishwei&lt;/a&gt; 的贴子 &lt;a href="https://ruby-china.org/topics/16187" title=""&gt;Rails 中的时区及时间问题&lt;/a&gt; 了解到&lt;code&gt;created_at&lt;/code&gt;字段不管有没有设置 &lt;code&gt;config.active_record.default_timezone = :local&lt;/code&gt; 都会记录 UTC 时间。&lt;/p&gt;

&lt;p&gt;所以我的问题是，如何让&lt;code&gt;created_at&lt;/code&gt;在 console 里默认就显示 localtime？而不是每次都要加&lt;code&gt;.localtime&lt;/code&gt; 或 &lt;code&gt;.getlocal('+08:00')&lt;/code&gt;。&lt;/p&gt;

&lt;p&gt;多谢回复。&lt;/p&gt;</description>
      <author>wfwdex</author>
      <pubDate>Thu, 11 May 2017 08:15:40 +0800</pubDate>
      <link>https://ruby-china.org/topics/32970</link>
      <guid>https://ruby-china.org/topics/32970</guid>
    </item>
    <item>
      <title>有没有办法让 Rails 不使用 schema_migrations 表来记录迁移？</title>
      <description>&lt;p&gt;事情是这样的：&lt;/p&gt;

&lt;p&gt;公司一个产品的数据需要进行远程同步，使用的是阿里的 otter。&lt;/p&gt;

&lt;p&gt;在配置同步的时候需要排除 schema_migrations 这个表来防止另一边的应用部署时产生问题。&lt;/p&gt;

&lt;p&gt;但 otter 配置正则表达式排除时会有问题，导致数据不同步。&lt;/p&gt;

&lt;p&gt;所以想问一下有没有别的方式来记录迁移，而不使用数据表？&lt;/p&gt;</description>
      <author>wfwdex</author>
      <pubDate>Wed, 10 May 2017 18:23:20 +0800</pubDate>
      <link>https://ruby-china.org/topics/32967</link>
      <guid>https://ruby-china.org/topics/32967</guid>
    </item>
    <item>
      <title>两个模型分别使用指定字段进行关联怎么实现？</title>
      <description>&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationRecord&lt;/span&gt;
  &lt;span class="c1"&gt;# fields: id, username, last_visit_domain&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Domain&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationRecord&lt;/span&gt;
  &lt;span class="c1"&gt;# field: id, domain, description&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;users 表：&lt;/p&gt;
&lt;table class="table table-bordered table-striped"&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;th&gt;id&lt;/th&gt;
&lt;th&gt;username&lt;/th&gt;
&lt;th&gt;last_visit_domain&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;david&lt;/td&gt;
&lt;td&gt;twitter.com&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;jacky&lt;/td&gt;
&lt;td&gt;facebook.com&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;domains 表：&lt;/p&gt;
&lt;table class="table table-bordered table-striped"&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;th&gt;id&lt;/th&gt;
&lt;th&gt;domain&lt;/th&gt;
&lt;th&gt;description&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;twitter.com&lt;/td&gt;
&lt;td&gt;推特&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;facebook.com&lt;/td&gt;
&lt;td&gt;非死不可&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;我分别有两个模型，想通过&lt;code&gt;User&lt;/code&gt;的&lt;code&gt;last_visit_domain&lt;/code&gt;字段关联到&lt;code&gt;Domain&lt;/code&gt;的&lt;code&gt;domain&lt;/code&gt;，然后得到每个&lt;code&gt;last_visit_domain&lt;/code&gt;对应的&lt;code&gt;description&lt;/code&gt;。&lt;/p&gt;

&lt;p&gt;在不使用 join 的前提下，请问同学们有没有办法利用 eager load 的方法，实现类似下面的效果？&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;username&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;last_visit_domain&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;description&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;david
twitter.com
推特
jacky
facebook.com
非死不可
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h2 id="(2017.05.15)找到一个手动eager load的方法:"&gt;(2017.05.15) 找到一个手动 eager load 的方法：&lt;/h2&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# 首先在取用户列表时，将当前页所有用户的 last_visit_domain 存入一个数组，去重去空&lt;/span&gt;
&lt;span class="n"&gt;users&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;page&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:page&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="n"&gt;last_visit_domains&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="ss"&gt;:last_visit_domain&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;compact!&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;uniq!&lt;/span&gt;
&lt;span class="c1"&gt;# 然后根据 last_visit_domains 找到相关的域名记录&lt;/span&gt;
&lt;span class="c1"&gt;# 重点是使用index_by将结果集转成以domain字段为key的hash&lt;/span&gt;
&lt;span class="n"&gt;domains&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Domain&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;domain: &lt;/span&gt;&lt;span class="n"&gt;last_visit_domains&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;index_by&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="ss"&gt;:domain&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# 显示每个用户时&lt;/span&gt;
&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="c1"&gt;# 找到 last_visit_domain 对应的域名的 description&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;domains&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;last_visit_domain&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;description&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;</description>
      <author>wfwdex</author>
      <pubDate>Tue, 25 Apr 2017 10:11:18 +0800</pubDate>
      <link>https://ruby-china.org/topics/32860</link>
      <guid>https://ruby-china.org/topics/32860</guid>
    </item>
    <item>
      <title>使用 Ruby 的大伙，你们常用的其他程序语言是什么？</title>
      <description>&lt;p&gt;除了正在使用或正在学习的 Ruby，大伙正在使用的主力或者非主力程序语言是什么？&lt;/p&gt;

&lt;hr&gt;

&lt;p&gt;截至到 27 楼，做了个统计排序：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JavaScript 9&lt;/li&gt;
&lt;li&gt;Golang 6&lt;/li&gt;
&lt;li&gt;Java 4&lt;/li&gt;
&lt;li&gt;C/C++ 3&lt;/li&gt;
&lt;li&gt;Elixir 3&lt;/li&gt;
&lt;li&gt;Python 3&lt;/li&gt;
&lt;li&gt;Crystal 2&lt;/li&gt;
&lt;li&gt;Swift 2&lt;/li&gt;
&lt;li&gt;C# 1&lt;/li&gt;
&lt;li&gt;Objective-C 1&lt;/li&gt;
&lt;/ul&gt;</description>
      <author>wfwdex</author>
      <pubDate>Sun, 26 Mar 2017 19:25:38 +0800</pubDate>
      <link>https://ruby-china.org/topics/32639</link>
      <guid>https://ruby-china.org/topics/32639</guid>
    </item>
    <item>
      <title>为什么在 select 里用 sum 查询，而 sum 消失了？</title>
      <description>&lt;p&gt;我有一个表 Device： &lt;/p&gt;
&lt;table class="table table-bordered table-striped"&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;th&gt;id&lt;/th&gt;
&lt;th&gt;model&lt;/th&gt;
&lt;th&gt;platform&lt;/th&gt;
&lt;th&gt;quantity&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;iphone7&lt;/td&gt;
&lt;td&gt;ios&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;iphone5&lt;/td&gt;
&lt;td&gt;ios&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;xiaomi4&lt;/td&gt;
&lt;td&gt;android&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;huawei&lt;/td&gt;
&lt;td&gt;android&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;我在 model 里加了个 scope 用来做 group 查询：&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;Device&lt;/span&gt;
   &lt;span class="n"&gt;scope&lt;/span&gt; &lt;span class="ss"&gt;:stat&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="nb"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"model, platform, SUM(quantity) AS total"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"model, platform"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;order&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"total DESC"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我在 controller 里调用：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DevicesController&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationController&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;stat&lt;/span&gt;
    &lt;span class="vi"&gt;@devices&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Device&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stat&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;但会出现错误：&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Mysql2::Error: Unknown column 'total' in 'order clause': SELECT COUNT(*) AS count_all, model, platform AS model_platform FROM &lt;code&gt;devices&lt;/code&gt; GROUP BY model, platform ORDER BY total DESC&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;就是说我的 scope 里的&lt;code&gt;SUM(quantity) AS total&lt;/code&gt;消失了。&lt;/p&gt;
&lt;h2 id="尝试"&gt;尝试&lt;/h2&gt;&lt;h3 id="在console里测试"&gt;在 console 里测试&lt;/h3&gt;
&lt;p&gt;我用&lt;code&gt;rails console&lt;/code&gt;打开，重新调用&lt;code&gt;Device.stat&lt;/code&gt;，发现又是正常的。&lt;/p&gt;
&lt;h3 id="去掉order"&gt;去掉 order&lt;/h3&gt;
&lt;p&gt;我把 scope 里的 order 去掉，log 中会输出如下两个信息：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(0.5ms)  SELECT COUNT(*) AS count_all, device_model, platform AS model_platform FROM `device` GROUP BY model, platform

Device Load (0.3ms)  SELECT model, platform, SUM(quantity) AS total FROM `devices` GROUP BY model, platform
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;感觉问题出在第一条语句上，为什么在 console 里会没有第一条语句，为什么第一条语句里会丢失 sum？&lt;/p&gt;</description>
      <author>wfwdex</author>
      <pubDate>Fri, 17 Mar 2017 12:09:15 +0800</pubDate>
      <link>https://ruby-china.org/topics/32560</link>
      <guid>https://ruby-china.org/topics/32560</guid>
    </item>
    <item>
      <title>在 Rails 中生成全局唯一 ID 的最佳实践是什么？</title>
      <description>&lt;p&gt;目前在做一个系统，数据库是 MySQL，数据是跨机房单向同步的，由节点服务器向主服务器同步数据，需要节点服务器能生成全局唯一 ID。&lt;/p&gt;

&lt;p&gt;目前在用的是 &lt;a href="https://github.com/sporkmonger/uuidtools" rel="nofollow" target="_blank" title=""&gt;uuidtools&lt;/a&gt; 这个 gem 生成 uuid。&lt;/p&gt;

&lt;p&gt;但生成的 uuid 有点长，而且数据大部分是日志，而且看了&lt;a href="https://ruby-china.org/topics/24509#reply-250046" title=""&gt;这个回复&lt;/a&gt;，觉得用 uuid 不妥，这几天想优化一下，找到另外一个方案：&lt;/p&gt;

&lt;p&gt;使用 &lt;a href="https://github.com/peterhellberg/hashids.rb" rel="nofollow" target="_blank" title=""&gt;hashids&lt;/a&gt; 这个 gem，每个节点服务器不同的 salt，然后再根据生成的 uuid 来生成 id。&lt;/p&gt;

&lt;p&gt;但 hashids 依然是生成字符型的，想请教一下有没有生成 bigint 的方法或者更好的方案？&lt;/p&gt;

&lt;hr&gt;

&lt;p&gt;ps: 由于 twitter 的 snowflake 需要另外搭建专用的 id 生成服务器，而节点服务器之间也是跨机房的，所以这个方案对我不适用。&lt;/p&gt;

&lt;p&gt;ps: 关闭讨论按钮总是被误点到。&lt;/p&gt;</description>
      <author>wfwdex</author>
      <pubDate>Thu, 16 Mar 2017 12:31:15 +0800</pubDate>
      <link>https://ruby-china.org/topics/32548</link>
      <guid>https://ruby-china.org/topics/32548</guid>
    </item>
    <item>
      <title>Rails API Only 模式下，怎么为 jbuilder 写 helper 方法？</title>
      <description>&lt;p&gt;在完整的 Rails 下，可以为 views 写 helper 方法，在 API Only 模式下，除了在 lib 里写，还有别的更好的方法吗？&lt;/p&gt;</description>
      <author>wfwdex</author>
      <pubDate>Thu, 29 Sep 2016 16:58:20 +0800</pubDate>
      <link>https://ruby-china.org/topics/31202</link>
      <guid>https://ruby-china.org/topics/31202</guid>
    </item>
    <item>
      <title>关于前后端分离项目的 Token 存储问题</title>
      <description>&lt;p&gt;目前在做一个前后端分离的项目，后端是 Rails5 API only，前端是用 vue.js，这是我第一次做，而且 vue.js 也是边学边做。&lt;/p&gt;

&lt;p&gt;在做认证的时候，我通过用户名 + 密码登录并获取服务端的 token，这时候我面临两个选择来存储这个 token。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;将 token 存在 cookie 里，为了防止 xss 攻击，最好要给 cookie 加上 httponly，而 Rails5 我用的是 API only 模式，不支持服务器下发 SET-COOKIE header&lt;/li&gt;
&lt;li&gt;将 token 存在 localStorage 中，但这样没办法防止 xss 攻击&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;请问大家一般是怎么解决这个问题的？有没有最佳实践？&lt;/p&gt;</description>
      <author>wfwdex</author>
      <pubDate>Thu, 22 Sep 2016 09:19:27 +0800</pubDate>
      <link>https://ruby-china.org/topics/31133</link>
      <guid>https://ruby-china.org/topics/31133</guid>
    </item>
    <item>
      <title>有没有可能两个 Rails 之间通过 RESTful 的 API 进行通信？</title>
      <description>&lt;p&gt;一个 rails app 只用来提供 API
另一个 rails 用来呈现和操作数据&lt;/p&gt;

&lt;p&gt;使用 vue 或 react 有一些学习成本，有没有相关的解决方案或者 Gems？&lt;/p&gt;

&lt;hr&gt;

&lt;p&gt;&lt;strong&gt;2016-11-24&lt;/strong&gt;&lt;br&gt;
发现个阿里的开源实现 &lt;a href="https://github.com/alibaba/otter" rel="nofollow" target="_blank"&gt;https://github.com/alibaba/otter&lt;/a&gt;  目前正在研究这个&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2016-12-14&lt;/strong&gt;&lt;br&gt;
又发现个商业软件，是用来远程同步数据库的 &lt;a href="http://www.pervasync.com/" rel="nofollow" target="_blank"&gt;http://www.pervasync.com/&lt;/a&gt; ，支持子集同步，差异冲突处理，断线重连等。&lt;/p&gt;</description>
      <author>wfwdex</author>
      <pubDate>Tue, 20 Sep 2016 20:34:09 +0800</pubDate>
      <link>https://ruby-china.org/topics/31115</link>
      <guid>https://ruby-china.org/topics/31115</guid>
    </item>
  </channel>
</rss>
