<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>justin (陆晓勇)</title>
    <link>https://ruby-china.org/justin</link>
    <description></description>
    <language>en-us</language>
    <item>
      <title>Reddot RubyConf 2016 总结</title>
      <description>&lt;p&gt;今年代表公司（&lt;a href="http://beansmile.com/" rel="nofollow" target="_blank" title=""&gt;Beansmile&lt;/a&gt;）前往新加坡参加&lt;code&gt;Reddot RubyConf&lt;/code&gt;, 收获满满，趁现在有时间，简单总结一下，供自己接下来的学习方向和目标，查漏补缺，也给未到场的朋友分享一下。
以下内容，仅供参考，如若有误，请指正。&lt;/p&gt;

&lt;p&gt;首先，我们来看下日程表&lt;/p&gt;

&lt;p&gt;&lt;img src="http://ww3.sinaimg.cn/large/785cd1e3gw1f59mpaj2ghj20kz0oa0xg.jpg" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;满满的都是干货，满满的都是大神，看得我那个鸡冻~~&lt;/p&gt;
&lt;h2 id="Day 1"&gt;Day 1&lt;/h2&gt;&lt;h3 id="Yukihiro (Matz) Matsumoto – Keynote: Ruby Typing"&gt;Yukihiro (Matz) Matsumoto – &lt;a href="https://engineers.sg/v/800" rel="nofollow" target="_blank" title=""&gt;Keynote: Ruby Typing&lt;/a&gt;
&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;Don't care about small things&lt;/code&gt; &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;第一个讲的是 Ruby 之父&lt;code&gt;Matz&lt;/code&gt;，以 O 型血的人不在意细节，分析动态语言和静态语言的区别入题，借此引入 Ruby 3 新 Feature&lt;code&gt;Soft Typing&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Types(part of ruby 3)

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://en.wikipedia.org/wiki/Duck_typing" rel="nofollow" target="_blank" title=""&gt;Duck typing&lt;/a&gt; in ruby(runtime)&lt;/li&gt;
&lt;li&gt;Don't check type on Programming&lt;/li&gt;
&lt;li&gt;Just care about behavior&lt;/li&gt;
&lt;li&gt;example for String.IO&lt;/li&gt;
&lt;li&gt;Don't care small things&lt;/li&gt;
&lt;li&gt;Soft Typing&lt;/li&gt;
&lt;li&gt;Don't challenge 100% coverage&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src="http://ww3.sinaimg.cn/large/785cd1e3gw1f59pdhnuysj21kw16otp6.jpg" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src="http://ww3.sinaimg.cn/large/785cd1e3gw1f59xnm36gaj20p00xcq69.jpg" title="" alt=""&gt;&lt;/p&gt;
&lt;h3 id="Jason Yeo – Slaying the Dragon"&gt;Jason Yeo – &lt;a href="https://speakerdeck.com/jsyeo/slaying-the-dragon-1" rel="nofollow" target="_blank" title=""&gt;Slaying the Dragon&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;先调侃了 Matz，设计了&lt;code&gt;Matzlisp&lt;/code&gt;的&lt;code&gt;Logo&lt;/code&gt;，注册了&lt;code&gt;matzLisp.org&lt;/code&gt;等等。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src="http://ww4.sinaimg.cn/large/785cd1e3gw1f5a5jaw6gfj21jq11qn6v.jpg" title="" alt=""&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;简单介绍&lt;a href="https://github.com/kanaka/mal" rel="nofollow" target="_blank" title=""&gt;mal&lt;/a&gt;的用法，了解 Lisp 的基本概念&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://rubinius.com/" rel="nofollow" target="_blank" title=""&gt;Rubinius&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com//queenfrankie/lani" rel="nofollow" target="_blank" title=""&gt;lani&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jsyeo/malady" rel="nofollow" target="_blank" title=""&gt;malady&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src="http://ww2.sinaimg.cn/large/785cd1e3gw1f59tvw7lm3j21kw16oqjl.jpg" title="" alt=""&gt;&lt;/p&gt;
&lt;h3 id="Kristine Joy Paas – Let's Play Ruby Golf"&gt;Kristine Joy Paas – &lt;a href="https://engineers.sg/v/802" rel="nofollow" target="_blank" title=""&gt;Let's Play Ruby Golf&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;各种 Ruby 黑魔法，请自我对比一下&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;正常情况&lt;/p&gt;

&lt;p&gt;&lt;img src="http://ww2.sinaimg.cn/large/785cd1e3gw1f5a7fkhgunj21600swdij.jpg" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;黑魔法情况下&lt;/p&gt;

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

&lt;p&gt;这是正常人看不懂的代码，所以通常情况下，这些写法在团队都是不推荐的，权当学习哈~&lt;/p&gt;

&lt;p&gt;&lt;img src="http://ww1.sinaimg.cn/large/785cd1e3gw1f59x8eak14j20zk0jz0t2.jpg" title="" alt=""&gt;&lt;/p&gt;
&lt;h3 id="Prathamesh Sonpatki – Secrets of testing Rails 5 apps"&gt;Prathamesh Sonpatki – &lt;a href="https://speakerdeck.com/chaitanya/secrets-of-testing-rails-5-apps-red-dot-ruby-conf-edition" rel="nofollow" target="_blank" title=""&gt;Secrets of testing Rails 5 apps&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;来自&lt;a href="https://www.bigbinary.com/" rel="nofollow" target="_blank" title=""&gt;bigbinary&lt;/a&gt;的博主，分享关于 Rails5 的一些内容&lt;/li&gt;
&lt;li&gt;Rails 5 integration test are default&lt;/li&gt;
&lt;li&gt;Rails 5 controller test are deprecated&lt;/li&gt;
&lt;li&gt;Active Job Async adapter&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;需要了解更多细节，请前往&lt;a href="http://blog.bigbinary.com/categories/Rails-5/" rel="nofollow" target="_blank" title=""&gt;Rails-5&lt;/a&gt;，里面满满的都是干货。&lt;/p&gt;

&lt;p&gt;&lt;img src="http://ww4.sinaimg.cn/large/785cd1e3gw1f59um0rclrj21kw16owxh.jpg" title="" alt=""&gt;&lt;/p&gt;
&lt;h3 id="Godfrey Chan – Keynote (coming soon)"&gt;Godfrey Chan – Keynote (&lt;em&gt;coming soon&lt;/em&gt;)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;授人以鱼不如授人以渔&lt;/li&gt;
&lt;li&gt;Probelm Solving&lt;/li&gt;
&lt;li&gt;Disruption&lt;/li&gt;
&lt;li&gt;The Traditional Path&lt;/li&gt;
&lt;li&gt;All abstractions leak&lt;/li&gt;
&lt;li&gt;Debugging&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src="http://ww4.sinaimg.cn/large/785cd1e3gw1f59ub69y6sj21kw16otrf.jpg" title="" alt=""&gt;
&lt;img src="http://ww3.sinaimg.cn/large/785cd1e3gw1f59udw4s2jj21kw16oae7.jpg" title="" alt=""&gt;&lt;/p&gt;
&lt;h3 id="Grzegorz Witek – Your API is too slow!"&gt;Grzegorz Witek – &lt;a href="https://speakerdeck.com/arnvald/your-api-is-too-slow" rel="nofollow" target="_blank" title=""&gt;Your API is too slow!&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;img src="http://ww2.sinaimg.cn/large/785cd1e3gw1f59uj3f5p7j21kw16o7nl.jpg" title="" alt=""&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Web app optimization&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src="http://ww3.sinaimg.cn/large/785cd1e3gw1f5a7md4rokj21kw0vygsu.jpg" title="" alt=""&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Web API optimization&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src="http://ww3.sinaimg.cn/large/785cd1e3gw1f5a7mwny95j21kw0vqwka.jpg" title="" alt=""&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;gem 'ruby-prof'&lt;/li&gt;
&lt;li&gt;gem 'rack-mini-profiler'&lt;/li&gt;
&lt;li&gt;gem 'newrelic'&lt;/li&gt;
&lt;li&gt;gem 'skylight'&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="Ligtning talks"&gt;&lt;em&gt;Ligtning talks&lt;/em&gt;&lt;/h3&gt;&lt;h4 id="Jo Cranford – Where Did Everybody Go?"&gt;Jo Cranford – &lt;a href="https://engineers.sg/v/806" rel="nofollow" target="_blank" title=""&gt;Where Did Everybody Go?&lt;/a&gt;
&lt;/h4&gt;
&lt;p&gt;主要是问卷调查，详情请看视频&lt;/p&gt;

&lt;p&gt;&lt;img src="http://ww2.sinaimg.cn/large/785cd1e3gw1f59xb2rnc6j20zk0jzwew.jpg" title="" alt=""&gt;&lt;/p&gt;
&lt;h4 id="SHIBATA Hiroshi – How to Begin Developing Ruby Core"&gt;SHIBATA Hiroshi – &lt;a href="http://www.slideshare.net/hsbt/how-to-begin-developing-ruby-core" rel="nofollow" target="_blank" title=""&gt;How to Begin Developing Ruby Core&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;介绍如何为 ruby 贡献源码&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src="http://ww1.sinaimg.cn/large/785cd1e3gw1f59xbkuta1j20zk0jzgm6.jpg" title="" alt=""&gt;&lt;/p&gt;
&lt;h4 id="Ankita Gupta – Speeding Up Your Test Suite"&gt;Ankita Gupta – &lt;a href="https://engineers.sg/v/808" rel="nofollow" target="_blank" title=""&gt;Speeding Up Your Test Suite&lt;/a&gt;
&lt;/h4&gt;
&lt;p&gt;&lt;img src="http://ww1.sinaimg.cn/large/785cd1e3gw1f59uo16zyqj21kw16owlx.jpg" title="" alt=""&gt;&lt;/p&gt;
&lt;h4 id="Giovanni Sakti – Flexible Authorization"&gt;Giovanni Sakti – &lt;a href="https://speakerdeck.com/giosakti/flexible-authorization" rel="nofollow" target="_blank" title=""&gt;Flexible Authorization&lt;/a&gt;
&lt;/h4&gt;
&lt;p&gt;&lt;img src="http://ww1.sinaimg.cn/large/785cd1e3gw1f59v5y2evjj20xc0p040t.jpg" title="" alt=""&gt;&lt;/p&gt;
&lt;h3 id="Tim Riley – Next-generation Ruby web apps with dry-rb, rom-rb, and Roda"&gt;Tim Riley – &lt;a href="http://dry-rb.org/resources/reddotrubyconf-2016" rel="nofollow" target="_blank" title=""&gt;Next-generation Ruby web apps with dry-rb, rom-rb, and Roda&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;简单介绍下一代 Web 框架&lt;a href="http://dry-rb.org/" rel="nofollow" target="_blank" title=""&gt;dry-rb&lt;/a&gt;，及各种主件&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/dry-rb" rel="nofollow" target="_blank" title=""&gt;dry-rb&lt;/a&gt; 源码&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rom-rb/rom" rel="nofollow" target="_blank" title=""&gt;rom-rb&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jeremyevans/roda" rel="nofollow" target="_blank" title=""&gt;roda&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/dry-rb/dry-web" rel="nofollow" target="_blank" title=""&gt;dry-web&lt;/a&gt; - Lightweight web application stack with pluggable routing front-ends&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src="http://ww4.sinaimg.cn/large/785cd1e3gw1f59v6oig8xj21kw16oaf9.jpg" title="" alt=""&gt;&lt;/p&gt;
&lt;h3 id="Sau Sheong Chang – Programming Complexity"&gt;Sau Sheong Chang – &lt;a href="https://speakerdeck.com/sausheong/programming-complexity" rel="nofollow" target="_blank" title=""&gt;Programming Complexity&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;img src="http://ww3.sinaimg.cn/large/785cd1e3gw1f59ukhlo69j21kw16owxs.jpg" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src="http://ww2.sinaimg.cn/large/785cd1e3gw1f59uqlvqp5j20xc0p00v0.jpg" title="" alt=""&gt;&lt;/p&gt;
&lt;h2 id="Day 2"&gt;Day 2&lt;/h2&gt;&lt;h3 id="Aaron Patterson – Keynote: Taking Out The Trash"&gt;Aaron Patterson – &lt;a href="https://engineers.sg/v/812" rel="nofollow" target="_blank" title=""&gt;Keynote: Taking Out The Trash&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/tenderlove/widen" rel="nofollow" target="_blank"&gt;https://github.com/tenderlove/widen&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;We don't care about small things, so we are removing downcase in Ruby 2.5&lt;/li&gt;
&lt;li&gt;Glossary&lt;/li&gt;
&lt;li&gt;Something About GC&lt;/li&gt;
&lt;li&gt;Find Unlink Node&lt;/li&gt;
&lt;li&gt;Remembered Set&lt;/li&gt;
&lt;li&gt;Incremental GC&lt;/li&gt;
&lt;li&gt;Algorithm&lt;/li&gt;
&lt;li&gt;Compacting&lt;/li&gt;
&lt;li&gt;heap layout&lt;/li&gt;
&lt;li&gt;&lt;a href="https://engineering.heroku.com/blogs/2015-02-04-incremental-gc/" rel="nofollow" target="_blank"&gt;https://engineering.heroku.com/blogs/2015-02-04-incremental-gc/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Ruby menmory Page &amp;amp;&amp;amp; OS menmory page&lt;/li&gt;
&lt;li&gt;GC::Profiler.report&lt;/li&gt;
&lt;li&gt;&lt;a href="http://ruby-doc.org/core-2.2.0/GC/Profiler.html" rel="nofollow" target="_blank"&gt;http://ruby-doc.org/core-2.2.0/GC/Profiler.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src="http://ww1.sinaimg.cn/large/785cd1e3gw1f5aphue0c1j21kw16oh2b.jpg" title="" alt=""&gt;
&lt;img src="http://ww1.sinaimg.cn/large/785cd1e3gw1f5apijx905j21kw16otpo.jpg" title="" alt=""&gt;&lt;/p&gt;
&lt;h3 id="Sameer Deshmukh – Scientific Computing in Ruby"&gt;Sameer Deshmukh – &lt;a href="https://speakerdeck.com/v0dro/scientific-computing-in-ruby-rdrc-2016" rel="nofollow" target="_blank" title=""&gt;Scientific Computing in Ruby&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Sameer Deshmukh&lt;/li&gt;
&lt;li&gt;&lt;a href="http://sciruby.com/" rel="nofollow" target="_blank"&gt;http://sciruby.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/domitry/nyaplot" rel="nofollow" target="_blank"&gt;https://github.com/domitry/nyaplot&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/v0dro/daru" rel="nofollow" target="_blank"&gt;https://github.com/v0dro/daru&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://t.co/22I21IxkMx" rel="nofollow" target="_blank"&gt;https://t.co/22I21IxkMx&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src="http://ww3.sinaimg.cn/large/785cd1e3gw1f5apiwo48pj21kw16owyg.jpg" title="" alt=""&gt;&lt;/p&gt;
&lt;h3 id="Konstantin Hasse – How We Replaced Salary Negotiations with a Sinatra App"&gt;Konstantin Hasse – &lt;a href="https://speakerdeck.com/rkh/how-we-replaced-salary-negotiations-with-a-sinatra-app" rel="nofollow" target="_blank" title=""&gt;How We Replaced Salary Negotiations with a Sinatra App&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;img src="http://ww2.sinaimg.cn/large/785cd1e3gw1f5apjnax8aj21kw1kwqso.jpg" title="" alt=""&gt;
&lt;img src="http://ww3.sinaimg.cn/large/785cd1e3gw1f5apk02vyfj21kw1kwaz4.jpg" title="" alt=""&gt;&lt;/p&gt;
&lt;h3 id="Vipul Amler – Rails Frontend: 2016 edition"&gt;Vipul Amler – &lt;a href="https://speakerdeck.com/vipulnsward/rails-frontend-2016-edition" rel="nofollow" target="_blank" title=""&gt;Rails Frontend: 2016 edition&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.bigbinary.com/building-modern-web-applications-with-reactjs" rel="nofollow" target="_blank"&gt;https://www.bigbinary.com/building-modern-web-applications-with-reactjs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://engineering.heroku.com/blogs/2016-02-18-speeding-up-sprockets/" rel="nofollow" target="_blank"&gt;https://engineering.heroku.com/blogs/2016-02-18-speeding-up-sprockets/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Sprockets Feature&lt;/li&gt;
&lt;li&gt;Headers(ETag,http_cache_forever)&lt;/li&gt;
&lt;li&gt;Caching(Action/View/ActionMailer,SQL)&lt;/li&gt;
&lt;li&gt;Layouts and Tags(async-defer)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src="http://ww4.sinaimg.cn/large/785cd1e3gw1f5aplexdqhj21kw1kwqqx.jpg" title="" alt=""&gt;
&lt;img src="http://ww2.sinaimg.cn/large/785cd1e3gw1f5aplqljqsj21kw1kwh91.jpg" title="" alt=""&gt;&lt;/p&gt;
&lt;h3 id="Sayanee Basu – Sense and Sensibility"&gt;Sayanee Basu – &lt;a href="https://talks.sayan.ee/sense" rel="nofollow" target="_blank" title=""&gt;Sense and Sensibility&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;img src="http://ww2.sinaimg.cn/large/785cd1e3gw1f5apmj5abqj21kw1kw7sz.jpg" title="" alt=""&gt;&lt;/p&gt;
&lt;h3 id="Yasuko Ohba – Our Fight Against Super Bad Patterns in Legacy Rails Apps"&gt;Yasuko Ohba – &lt;a href="https://engineers.sg/v/817" rel="nofollow" target="_blank" title=""&gt;Our Fight Against Super Bad Patterns in Legacy Rails Apps&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;img src="http://ww4.sinaimg.cn/large/785cd1e3gw1f5apmunnbfj21kw16owyt.jpg" title="" alt=""&gt;&lt;/p&gt;
&lt;h3 id="Lightning talks"&gt;&lt;em&gt;Lightning talks&lt;/em&gt;&lt;/h3&gt;&lt;h4 id="Kenji Mori – Learning Through Blogging: Ruby Blogging Benefits"&gt;Kenji Mori – &lt;a href="https://speakerdeck.com/morizyun/learning-through-blogging-ruby-blogging-benefits" rel="nofollow" target="_blank" title=""&gt;Learning Through Blogging: Ruby Blogging Benefits&lt;/a&gt;
&lt;/h4&gt;
&lt;p&gt;&lt;img src="http://ww2.sinaimg.cn/large/785cd1e3gw1f5aqni6tihj21380tawhe.jpg" title="" alt=""&gt;&lt;/p&gt;
&lt;h4 id="Jack Chen Songyong – Grow from Small Simple Steps"&gt;Jack Chen Songyong – &lt;a href="https://speakerdeck.com/aquajach/grow-from-small-simple-steps" rel="nofollow" target="_blank" title=""&gt;Grow from Small Simple Steps&lt;/a&gt;
&lt;/h4&gt;
&lt;p&gt;&lt;img src="http://ww1.sinaimg.cn/large/785cd1e3gw1f5apyrxhvdj21kw16oaso.jpg" title="" alt=""&gt;&lt;/p&gt;
&lt;h4 id="Yuki Nishijima – 20 Tools and Techniques that Make You More Creative"&gt;Yuki Nishijima – &lt;a href="https://speakerdeck.com/yuki24/20-tools-and-techniques-that-make-you-more-creative" rel="nofollow" target="_blank" title=""&gt;20 Tools and Techniques that Make You More Creative&lt;/a&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;gem "did you mean/experimental"&lt;/li&gt;
&lt;li&gt;budnle config --global jobs 16&lt;/li&gt;
&lt;li&gt;app.get "/"&lt;/li&gt;
&lt;li&gt;minitest-power_assert&lt;/li&gt;
&lt;li&gt;mv /path/{old, new}.rb/&lt;/li&gt;
&lt;li&gt;ctrl + R&lt;/li&gt;
&lt;li&gt;tree&lt;/li&gt;
&lt;li&gt;ag/ lick ack&lt;/li&gt;
&lt;li&gt;curl xxxxx | jq .dependecies.development&lt;/li&gt;
&lt;li&gt;pagmentize   alise 'more'=&lt;code&gt;pagmentize -g&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src="http://ww1.sinaimg.cn/large/785cd1e3gw1f5aq5c3a7lj20zk0qoq4n.jpg" title="" alt=""&gt;&lt;/p&gt;
&lt;h4 id="Steven Yap – Building Real-Time App with React/Redux/Rails/RethinkDB"&gt;Steven Yap – &lt;a href="https://engineers.sg/v/821" rel="nofollow" target="_blank" title=""&gt;Building Real-Time App with React/Redux/Rails/RethinkDB&lt;/a&gt;
&lt;/h4&gt;
&lt;p&gt;&lt;img src="http://ww2.sinaimg.cn/large/785cd1e3gw1f5aq5tg4cjj20zk0qoq49.jpg" title="" alt=""&gt;&lt;/p&gt;
&lt;h4 id="Xin Tian – Journey to becoming a techlady"&gt;Xin Tian – &lt;a href="https://engineers.sg/v/822" rel="nofollow" target="_blank" title=""&gt;Journey to becoming a techlady&lt;/a&gt;
&lt;/h4&gt;
&lt;p&gt;&lt;img src="http://ww4.sinaimg.cn/large/785cd1e3gw1f5aqpgzch4j21kw0udtf2.jpg" title="" alt=""&gt;&lt;/p&gt;
&lt;h3 id="Kir Shatrov – Building a ChatOps framework"&gt;Kir Shatrov – &lt;a href="https://gist.github.com/kirs/a0b69608a96b7845f669822bd7852d9f" rel="nofollow" target="_blank" title=""&gt;Building a ChatOps framework&lt;/a&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="lita" title=""&gt;https://github.com/litaio/lita&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src="http://ww1.sinaimg.cn/large/785cd1e3gw1f5apodvprfj21kw16oh5d.jpg" title="" alt=""&gt;&lt;/p&gt;
&lt;h3 id="Terence Lee - Closing Keynote: After a Decade, Still a Rubyist - RedDotRubyConf 2016"&gt;Terence Lee - &lt;a href="https://www.youtube.com/watch?v=5WZmE3uXRWw&amp;amp;list=PLECEw2eFfW7iiJpXtb_cYeKv5_A6Pd1tl&amp;amp;index=24" rel="nofollow" target="_blank" title=""&gt;Closing Keynote: After a Decade, Still a Rubyist - RedDotRubyConf 2016&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;img src="http://ww3.sinaimg.cn/large/785cd1e3gw1f5apov9qcfj21kw16owxi.jpg" title="" alt=""&gt;&lt;/p&gt;
&lt;h3 id="图片"&gt;图片&lt;/h3&gt;
&lt;p&gt;中国参会 Rubyist 合照&lt;/p&gt;

&lt;p&gt;&lt;img src="http://ww1.sinaimg.cn/large/785cd1e3jw1f5aptfdeupj21kw16oh5f.jpg" title="" alt=""&gt;&lt;/p&gt;
&lt;h4 id="新加坡美景"&gt;新加坡美景&lt;/h4&gt;
&lt;p&gt;夜景
&lt;img src="http://ww2.sinaimg.cn/large/785cd1e3gw1f5apuw09klj21kw16o7qw.jpg" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;标志性建筑
&lt;img src="http://ww4.sinaimg.cn/large/785cd1e3gw1f5apvdxmqfj21kw16oh7a.jpg" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src="http://ww3.sinaimg.cn/large/785cd1e3gw1f5apw7akyqj21kw16o1kp.jpg" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src="http://ww2.sinaimg.cn/large/785cd1e3gw1f5apwlsz4mj21kw16o1hv.jpg" title="" alt=""&gt;&lt;/p&gt;
&lt;h3 id="各种资源"&gt;各种资源&lt;/h3&gt;&lt;h4 id="官网"&gt;官网&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.reddotrubyconf.com/" rel="nofollow" target="_blank"&gt;http://www.reddotrubyconf.com/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="直播视频"&gt;直播视频&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=_3sz2Oex2YQ" rel="nofollow" target="_blank" title=""&gt;Day 1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=nu3oVW1c66A" rel="nofollow" target="_blank" title=""&gt;Day 2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;完整视频播放列表 📺&lt;a href="https://www.youtube.com/playlist?list=PLECEw2eFfW7iiJpXtb_cYeKv5_A6Pd1tl" rel="nofollow" target="_blank"&gt;https://www.youtube.com/playlist?list=PLECEw2eFfW7iiJpXtb_cYeKv5_A6Pd1tl&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="RedDotRubyConf 2016 links &amp;amp; resources"&gt;&lt;a href="https://gist.github.com/cheeaun/43843c8b1c764825b9f3d63ed8f5bd78" rel="nofollow" target="_blank" title=""&gt;RedDotRubyConf 2016 links &amp;amp; resources&lt;/a&gt;&lt;/h4&gt;&lt;h4 id="现场3D图"&gt;&lt;a href="https://theta360.com/s/mLWd3XTvDsBTQVikyhOtt7wMm" rel="nofollow" target="_blank" title=""&gt;现场 3D 图&lt;/a&gt;&lt;/h4&gt;</description>
      <author>justin</author>
      <pubDate>Mon, 27 Jun 2016 23:55:41 +0800</pubDate>
      <link>https://ruby-china.org/topics/30379</link>
      <guid>https://ruby-china.org/topics/30379</guid>
    </item>
    <item>
      <title>[广州][2015年07月22日 19:00] GZRUBY 第 26 次聚会 [微信开发专场] </title>
      <description>&lt;p&gt;Hello Rubyist! 
距离上一次&lt;a href="https://ruby-china.org/topics/25468" title=""&gt;GZRUBY 聚会&lt;/a&gt;已经两个月了，现在我们已经迎来了燥热的夏天。
我们发现最近使用 ruby 开发微信应用的团队越来越多了。
大家在开发微信应用的时候有踩过什么坑吗？
大家对微信的接口有什么想吐槽了的吗？
大家有什么用微信开发的有趣的小应用想分享出来的吗？
大家对微信上开发 app 前景是怎么看的呢？
大家对微信运营方面有什么心得吗？&lt;/p&gt;

&lt;p&gt;欢迎大家带上自己的主题，让我们聚在一起分享吧！&lt;/p&gt;
&lt;h3 id="已报名主题"&gt;已报名主题&lt;/h3&gt;
&lt;p&gt;这次我们的主题是基于微信的。欢迎任何与微信相关的话题或者演讲。
我们还在此持续更新我们收集到的演讲主题名称，请大家踊跃报名。&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="/ruby_sky" class="user-mention" title="@ruby_sky"&gt;&lt;i&gt;@&lt;/i&gt;ruby_sky&lt;/a&gt;（weixin_rails_middleware gem 作者） 《ruby 与微信开发那些事》&lt;/li&gt;
&lt;li&gt;
&lt;a href="/rainchen" class="user-mention" title="@rainchen"&gt;&lt;i&gt;@&lt;/i&gt;rainchen&lt;/a&gt;  《友约 v0.4 开发经验分享—微信与 react 中踩过的那些坑》&lt;/li&gt;
&lt;li&gt;duxiaolong《关于微信上适合开发什么样的应用的一些思考？》&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="活动时间"&gt;活动时间&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;时间/When: 星期三－7 月 22 号 19:00 / July 22, 19:00 PM&lt;/li&gt;
&lt;li&gt;聚会安排:

&lt;ul&gt;
&lt;li&gt;19:00-19:45 主题演讲&lt;/li&gt;
&lt;li&gt;19:45-20:00 茶歇休息&lt;/li&gt;
&lt;li&gt;20:00-20:45 主题演讲&lt;/li&gt;
&lt;li&gt;20:45-21:30 茶歇休息 &amp;amp; 自由交流&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="活动报名"&gt;活动报名&lt;/h3&gt;
&lt;p&gt;这次我们的报名采用由&lt;a href="http://beansmile.com/" rel="nofollow" target="_blank" title=""&gt;Beansmile&lt;/a&gt;团队内部开发的一款基于微信的活动报名签到的应用。
前端采用 reactjs 实现。大家扫一扫二维码就可以报名参加了。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/2015/6f658d8ba9743eab215e3d7400d0f895.jpg" title="" alt=""&gt;&lt;/p&gt;
&lt;h3 id="活动场地"&gt;活动场地&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;地点/Where: 广东省广州市海珠区新港中路 397 号 T.I.T 创意园创意大道 06 号 CCIC 联合文创（因为百度地图没有此处地址数据，需要导航的建议用腾讯地图）&lt;/li&gt;
&lt;li&gt;地铁/Metro: 客村 A 出口/Line 3 - Ke Cun, Exit A
&lt;img src="https://l.ruby-china.com/photo/2014/e8a6d49d28fc355e2f55675e7abc0e19.png" title="" alt="客村A出口"&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="联系方式"&gt;联系方式&lt;/h3&gt;
&lt;p&gt;Email: justin at beansmile.com
wechat: justin_lu_xiao_yong&lt;/p&gt;</description>
      <author>justin</author>
      <pubDate>Mon, 06 Jul 2015 20:48:48 +0800</pubDate>
      <link>https://ruby-china.org/topics/26349</link>
      <guid>https://ruby-china.org/topics/26349</guid>
    </item>
    <item>
      <title>Rails Scopes 预加载</title>
      <description>&lt;p&gt;前几天在&lt;a href="http://rubyweekly.com/" rel="nofollow" target="_blank" title=""&gt;rubyweekly&lt;/a&gt;里面看到一篇文章，感觉写得不错。拿出来分享一下。&lt;a href="http://www.justinweiss.com/blog/2015/06/23/how-to-preload-rails-scopes/?utm_source=rubyweekly&amp;amp;utm_medium=email" rel="nofollow" target="_blank" title=""&gt;原文&lt;/a&gt;更精彩&lt;/p&gt;
&lt;h2 id="scope 会造成N+1查询"&gt;scope 会造成 N+1 查询&lt;/h2&gt;
&lt;p&gt;作为一个 Rails 开发者，我们经常使用&lt;a href="http://guides.rubyonrails.org/active_record_querying.html#scopes" rel="nofollow" target="_blank" title=""&gt;scope&lt;/a&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;Review&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;
  &lt;span class="n"&gt;belongs_to&lt;/span&gt; &lt;span class="ss"&gt;:restaurant&lt;/span&gt;

  &lt;span class="n"&gt;scope&lt;/span&gt; &lt;span class="ss"&gt;:positive&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="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"rating &amp;gt; 3.0"&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;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;Restaurant&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reviews&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;positive&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;count&lt;/span&gt;
  &lt;span class="no"&gt;Restaurant&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;`restaurants`&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;`restaurants`&lt;/span&gt;  &lt;span class="no"&gt;ORDER&lt;/span&gt; &lt;span class="no"&gt;BY&lt;/span&gt; &lt;span class="sb"&gt;`restaurants`&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;` ASC LIMIT 1
   (0.6ms)  SELECT COUNT(*) FROM `&lt;/span&gt;&lt;span class="n"&gt;reviews&lt;/span&gt;&lt;span class="sb"&gt;` WHERE `&lt;/span&gt;&lt;span class="n"&gt;reviews&lt;/span&gt;&lt;span class="sb"&gt;`.`&lt;/span&gt;&lt;span class="n"&gt;restaurant_id&lt;/span&gt;&lt;span class="sb"&gt;` = 1 AND (rating &amp;gt; 3.0)
=&amp;gt; 5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;但是，当你一不小心，这将严重的影响你应用的性能。
为什么呢？因为使用&lt;code&gt;scope&lt;/code&gt;进行定义的查询并不会被预加载。
假设你要查询一些&lt;code&gt;restaurants&lt;/code&gt;所有&lt;code&gt;positive reviews&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="n"&gt;restauraunts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Restaurant&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="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;002&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="n"&gt;restauraunts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&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;restaurant&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&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;003&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;*&lt;/span&gt;   &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;restaurant&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="si"&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;restaurant&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reviews&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;positive&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;length&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; positive reviews."&lt;/span&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;004&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;gt;&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="no"&gt;Review&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.6&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;`reviews`&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;`reviews`&lt;/span&gt; &lt;span class="no"&gt;WHERE&lt;/span&gt; &lt;span class="sb"&gt;`reviews`&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;`&lt;/span&gt;&lt;span class="n"&gt;restaurant_id&lt;/span&gt;&lt;span class="sb"&gt;` = 1 AND (rating &amp;gt; 3.0)
  Review Load (0.5ms)  SELECT `&lt;/span&gt;&lt;span class="n"&gt;reviews&lt;/span&gt;&lt;span class="sb"&gt;`.* FROM `&lt;/span&gt;&lt;span class="n"&gt;reviews&lt;/span&gt;&lt;span class="sb"&gt;` WHERE `&lt;/span&gt;&lt;span class="n"&gt;reviews&lt;/span&gt;&lt;span class="sb"&gt;`.`&lt;/span&gt;&lt;span class="n"&gt;restaurant_id&lt;/span&gt;&lt;span class="sb"&gt;` = 2 AND (rating &amp;gt; 3.0)
  Review Load (0.7ms)  SELECT `&lt;/span&gt;&lt;span class="n"&gt;reviews&lt;/span&gt;&lt;span class="sb"&gt;`.* FROM `&lt;/span&gt;&lt;span class="n"&gt;reviews&lt;/span&gt;&lt;span class="sb"&gt;` WHERE `&lt;/span&gt;&lt;span class="n"&gt;reviews&lt;/span&gt;&lt;span class="sb"&gt;`.`&lt;/span&gt;&lt;span class="n"&gt;restaurant_id&lt;/span&gt;&lt;span class="sb"&gt;` = 3 AND (rating &amp;gt; 3.0)
  Review Load (0.7ms)  SELECT `&lt;/span&gt;&lt;span class="n"&gt;reviews&lt;/span&gt;&lt;span class="sb"&gt;`.* FROM `&lt;/span&gt;&lt;span class="n"&gt;reviews&lt;/span&gt;&lt;span class="sb"&gt;` WHERE `&lt;/span&gt;&lt;span class="n"&gt;reviews&lt;/span&gt;&lt;span class="sb"&gt;`.`&lt;/span&gt;&lt;span class="n"&gt;restaurant_id&lt;/span&gt;&lt;span class="sb"&gt;` = 4 AND (rating &amp;gt; 3.0)
  Review Load (0.7ms)  SELECT `&lt;/span&gt;&lt;span class="n"&gt;reviews&lt;/span&gt;&lt;span class="sb"&gt;`.* FROM `&lt;/span&gt;&lt;span class="n"&gt;reviews&lt;/span&gt;&lt;span class="sb"&gt;` WHERE `&lt;/span&gt;&lt;span class="n"&gt;reviews&lt;/span&gt;&lt;span class="sb"&gt;`.`&lt;/span&gt;&lt;span class="n"&gt;restaurant_id&lt;/span&gt;&lt;span class="sb"&gt;` = 5 AND (rating &amp;gt; 3.0)
=&amp;gt; ["Judd's Pub: 5 positive reviews.", "Felix's Nightclub: 6 positive reviews.", "Mabel's Burrito Shack: 7 positive reviews.", "Kendall's Burrito Shack: 2 positive reviews.", "Elisabeth's Deli: 15 positive reviews."]
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我们可以看到，&lt;code&gt;scope:positive&lt;/code&gt;并没有被缓存起来，这明显的是一个&lt;code&gt;N+1&lt;/code&gt;查询。&lt;/p&gt;
&lt;h2 id="用associations代替scopes"&gt;用 associations 代替 scopes&lt;/h2&gt;
&lt;p&gt;我们可以通过用 associations 代替 scopes，来避免这个问题。请看下面例子：&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;Restaurant&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;
  &lt;span class="n"&gt;has_many&lt;/span&gt; &lt;span class="ss"&gt;:reviews&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;当我们查看这个&lt;a href="http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html" rel="nofollow" target="_blank" title=""&gt;文档&lt;/a&gt;时，我们可以看到，&lt;code&gt;has_many&lt;/code&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;Restaurant&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;
  &lt;span class="n"&gt;has_many&lt;/span&gt; &lt;span class="ss"&gt;:reviews&lt;/span&gt;
  &lt;span class="n"&gt;has_many&lt;/span&gt; &lt;span class="ss"&gt;:positive_reviews&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="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"rating &amp;gt; 3.0"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="ss"&gt;class_name: &lt;/span&gt;&lt;span class="s2"&gt;"Review"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;但我们可以这样子获取一个&lt;code&gt;restaurant&lt;/code&gt;的所有&lt;code&gt;positive_reviews&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;Restaurant&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;positive_reviews&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;count&lt;/span&gt;
  &lt;span class="no"&gt;Restaurant&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.2&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;`restaurants`&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;`restaurants`&lt;/span&gt;  &lt;span class="no"&gt;ORDER&lt;/span&gt; &lt;span class="no"&gt;BY&lt;/span&gt; &lt;span class="sb"&gt;`restaurants`&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;` ASC LIMIT 1
   (0.4ms)  SELECT COUNT(*) FROM `&lt;/span&gt;&lt;span class="n"&gt;reviews&lt;/span&gt;&lt;span class="sb"&gt;` WHERE `&lt;/span&gt;&lt;span class="n"&gt;reviews&lt;/span&gt;&lt;span class="sb"&gt;`.`&lt;/span&gt;&lt;span class="n"&gt;restaurant_id&lt;/span&gt;&lt;span class="sb"&gt;` = 1 AND (rating &amp;gt; 3.0)
=&amp;gt; 5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后我们就可以通过&lt;code&gt;include&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="n"&gt;restauraunts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Restaurant&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;:positive_reviews&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="no"&gt;Restaurant&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.3&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;`restaurants`&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;`restaurants`&lt;/span&gt;  &lt;span class="no"&gt;ORDER&lt;/span&gt; &lt;span class="no"&gt;BY&lt;/span&gt; &lt;span class="sb"&gt;`restaurants`&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;` ASC LIMIT 5
  Review Load (1.2ms)  SELECT `&lt;/span&gt;&lt;span class="n"&gt;reviews&lt;/span&gt;&lt;span class="sb"&gt;`.* FROM `&lt;/span&gt;&lt;span class="n"&gt;reviews&lt;/span&gt;&lt;span class="sb"&gt;` WHERE (rating &amp;gt; 3.0) AND `&lt;/span&gt;&lt;span class="n"&gt;reviews&lt;/span&gt;&lt;span class="sb"&gt;`.`&lt;/span&gt;&lt;span class="n"&gt;restaurant_id&lt;/span&gt;&lt;span class="sb"&gt;` IN (1, 2, 3, 4, 5)
irb(main):002:0&amp;gt; restauraunts.map do |restaurant|
irb(main):003:1*   "&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;restaurant&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;restaurant&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;positive_reviews&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;length&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt; positive reviews."
irb(main):004:1&amp;gt; end
=&amp;gt; ["Judd's Pub: 5 positive reviews.", "Felix's Nightclub: 6 positive reviews.", "Mabel's Burrito Shack: 7 positive reviews.", "Kendall's Burrito Shack: 2 positive reviews.", "Elisabeth's Deli: 15 positive reviews."]
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;至此，6 个 Sql 查询变成 2 个&lt;/p&gt;
&lt;h2 id="消除重复"&gt;消除重复&lt;/h2&gt;
&lt;p&gt;现在我们定义了一个&lt;code&gt;scope:positive&lt;/code&gt;和一个关系&lt;code&gt;has_many :positive_reviews&lt;/code&gt;，我们可以看到，它们是重复的。我们可以简单的消除这个 DRY.&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;Review&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;
  &lt;span class="n"&gt;belongs_to&lt;/span&gt; &lt;span class="ss"&gt;:restaurant&lt;/span&gt;

  &lt;span class="n"&gt;scope&lt;/span&gt; &lt;span class="ss"&gt;:positive&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="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"rating &amp;gt; 3.0"&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="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Restaurant&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;
  &lt;span class="n"&gt;has_many&lt;/span&gt; &lt;span class="ss"&gt;:reviews&lt;/span&gt;
  &lt;span class="n"&gt;has_many&lt;/span&gt; &lt;span class="ss"&gt;:positive_reviews&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="n"&gt;positive&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="ss"&gt;class_name: &lt;/span&gt;&lt;span class="s2"&gt;"Review"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;至此，我们可以知道&lt;code&gt;scope&lt;/code&gt;虽然好用，但是当你发现的代码出现以上问题时，简单的修改，能减少许多&lt;code&gt;sql&lt;/code&gt;查询&lt;/p&gt;

&lt;p&gt;文章没有逐字翻译，如有问题，麻烦指出。&lt;/p&gt;</description>
      <author>justin</author>
      <pubDate>Fri, 03 Jul 2015 21:59:33 +0800</pubDate>
      <link>https://ruby-china.org/topics/26323</link>
      <guid>https://ruby-china.org/topics/26323</guid>
    </item>
    <item>
      <title>理解 ActiveSupport::Concern </title>
      <description>&lt;p&gt;分享一下自己阅读 ActiveSupport::Concern 源码的过程，希望和大家一起学习，错误之处，还请指出&lt;/p&gt;

&lt;p&gt;在查看 ActiveSupport::Concern &lt;a href="https://github.com/rails/rails/blob/master/activesupport/lib/active_support/concern.rb" rel="nofollow" target="_blank" title=""&gt;源码&lt;/a&gt;之前，我们先理解几个概念&lt;/p&gt;
&lt;h2 id="class_eval and instance_eval"&gt;class_eval and instance_eval&lt;/h2&gt;&lt;h3 id="instance_eval"&gt;instance_eval&lt;/h3&gt;
&lt;p&gt;首先从名字可以得到的信息是，&lt;code&gt;instance_eval&lt;/code&gt;的调用者&lt;code&gt;receiver&lt;/code&gt;必须是一个实例&lt;code&gt;instance&lt;/code&gt;，而在&lt;code&gt;instance_eval&lt;/code&gt; block 的内部，self 即为 receiver 实例本身。&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# 例子一&lt;/span&gt;
&lt;span class="n"&gt;obj_instance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;instance_eval&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="nb"&gt;self&lt;/span&gt;  &lt;span class="c1"&gt;# =&amp;gt; obj_instance&lt;/span&gt;
  &lt;span class="c1"&gt;# current class =&amp;gt; obj_instance's singleton class&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;根据这个定义，如果在一个实例上调用了&lt;code&gt;instance_eval&lt;/code&gt;，就可以在其中定义该实例的单态函数&lt;code&gt;singleton_method&lt;/code&gt;&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# 例子二&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;A&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;A&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;
&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;instance_eval&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;  &lt;span class="c1"&gt;# =&amp;gt; a&lt;/span&gt;
  &lt;span class="c1"&gt;# current class =&amp;gt; a's singleton class&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;method1&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"this is a singleton method of instance a"&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;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;method1&lt;/span&gt;
&lt;span class="c1"&gt;#=&amp;gt; this is a singleton method of instance a&lt;/span&gt;

&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;A&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;
&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;method1&lt;/span&gt;
&lt;span class="c1"&gt;#=&amp;gt; NoMethodError: undefined method `method1' for #&amp;lt;A:0x007fbc2ced9550&amp;gt;&lt;/span&gt;
&lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pry&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="ss"&gt;:in&lt;/span&gt; &lt;span class="sb"&gt;`&amp;lt;main&amp;gt;'

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如我们所知，因为类本身也是 Class 类的一个实例，instance_eval 也可以用在类上，这个时候就可以在其中定义该类的 singleton_method，即为该类的类方法。&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# 例子三&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;A&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="no"&gt;A&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;instance_eval&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;  &lt;span class="c1"&gt;# =&amp;gt; A&lt;/span&gt;
  &lt;span class="c1"&gt;# current class =&amp;gt; A's singleton class&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;method1&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s1"&gt;'this is a singleton method of class A'&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;A&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;method1&lt;/span&gt;
&lt;span class="c1"&gt;# this is a singleton method of class A&lt;/span&gt;
&lt;span class="c1"&gt;#=&amp;gt;  nil&lt;/span&gt;

&lt;span class="c1"&gt;#=&amp;gt; NoMethodError: undefined method `method1' for #&amp;lt;A:0x007fbc3009e180&amp;gt;&lt;/span&gt;
&lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pry&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="ss"&gt;:in&lt;/span&gt; &lt;span class="sb"&gt;`&amp;lt;main&amp;gt;'

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="class_eval"&gt;class_eval&lt;/h3&gt;
&lt;p&gt;再来看&lt;code&gt;class_eval&lt;/code&gt;，首先从名字可以得到的信息是，class_eval 的调用者 receiver 必须是一个类，而在&lt;code&gt;class_eval&lt;/code&gt; &lt;code&gt;block&lt;/code&gt;的内部，&lt;code&gt;self&lt;/code&gt;即为 receiver 类本身。&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# 例子四&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;A&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="no"&gt;A&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;class_eval&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;  
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; A&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;根据这个定义，如果在一个类上调用了 class_eval，就可以在其中定义该类的实例方法 (instance_method)，例如&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# 例子五&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;A&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;A&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;
&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;method1&lt;/span&gt;
&lt;span class="c1"&gt;#=&amp;gt; NoMethodError: undefined method `method1' for &amp;lt;A:0x007fbc29a826f8&amp;gt; from (pry):21:in `&amp;lt;main&amp;gt;'&lt;/span&gt;

&lt;span class="no"&gt;A&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;class_eval&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;method1&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s1"&gt;'this is a instance method of class A'&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;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;method1&lt;/span&gt;
&lt;span class="c1"&gt;#=&amp;gt; this is a instance method of class A&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;综合上面例子，我们可得出&lt;/p&gt;

&lt;p&gt;1. &lt;code&gt;instance_eval&lt;/code&gt;必须由 instance 来调用，可以用来定义单例函数（&lt;code&gt;singleton_methods&lt;/code&gt;)
    2. &lt;code&gt;class_eval&lt;/code&gt;必须是由 class 来调用，可以用来定义类的实例方法 (&lt;code&gt;instance_methods&lt;/code&gt;)&lt;/p&gt;
&lt;h2 id="include and extend"&gt;include and extend&lt;/h2&gt;
&lt;p&gt;废话不多说，先看代码：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# 例子六&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Foo&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;foo&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s1"&gt;'foo method with include...'&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;class&lt;/span&gt; &lt;span class="nc"&gt;Bar&lt;/span&gt;
  &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;Foo&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="no"&gt;Bar&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;foo&lt;/span&gt; 
&lt;span class="c1"&gt;# foo method with include...&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; nil&lt;/span&gt;
&lt;span class="no"&gt;Bar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;foo&lt;/span&gt; 
&lt;span class="c1"&gt;# NoMethodError: undefined method `foo' for Bar:Class&lt;/span&gt;
&lt;span class="c1"&gt;# from (pry):75:in `&amp;lt;main&amp;gt;'&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Baz&lt;/span&gt;
  &lt;span class="kp"&gt;extend&lt;/span&gt; &lt;span class="no"&gt;Foo&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="no"&gt;Baz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;foo&lt;/span&gt;
&lt;span class="c1"&gt;# foo method with include...&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; nil&lt;/span&gt;

&lt;span class="no"&gt;Baz&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;foo&lt;/span&gt;
&lt;span class="c1"&gt;# NoMethodError: undefined method `foo' for #&amp;lt;Baz:0x007f8061dec068&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;# from (pry):80:in `&amp;lt;main&amp;gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;由例子我们可以看出，&lt;code&gt;include&lt;/code&gt;会把&lt;code&gt;module&lt;/code&gt;的方法变成实例方法，&lt;code&gt;extend&lt;/code&gt; 会把方法变成类方法。
但是，大多时候我们也可以用&lt;code&gt;include&lt;/code&gt;来实现类方法和实例方法，请看以下例子：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# 例子七&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Foo&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;included&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;extend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;ClassMethods&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;module&lt;/span&gt; &lt;span class="nn"&gt;ClassMethods&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;bar&lt;/span&gt;
      &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s1"&gt;'class method'&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;def&lt;/span&gt; &lt;span class="nf"&gt;foo&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s1"&gt;'instance method'&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;class&lt;/span&gt; &lt;span class="nc"&gt;Baz&lt;/span&gt;
  &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;Foo&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="no"&gt;Baz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bar&lt;/span&gt;
&lt;span class="c1"&gt;# class method&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; nil&lt;/span&gt;
&lt;span class="no"&gt;Baz&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;foo&lt;/span&gt;
&lt;span class="c1"&gt;# instance method&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; nil&lt;/span&gt;
&lt;span class="no"&gt;Baz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;foo&lt;/span&gt;
&lt;span class="c1"&gt;# NoMethodError: undefined method `foo' for Baz:Class&lt;/span&gt;
&lt;span class="no"&gt;Baz&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;bar&lt;/span&gt;
&lt;span class="c1"&gt;# NoMethodError: undefined method `bar' for #&amp;lt;Baz:0x007fbc30274ab8&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;从例子我们可以看出，&lt;code&gt;include&lt;/code&gt;有一个叫&lt;code&gt;included&lt;/code&gt;的钩子，正是通过这个钩子，我们可以用&lt;code&gt;include&lt;/code&gt;实现添加类方法和实例方法
我们来看看&lt;code&gt;included&lt;/code&gt;这个钩子到底做了什么？&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;A&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;included&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mod&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; included in &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;mod&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;end&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Enumerable&lt;/span&gt;
  &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;A&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="c1"&gt;# A included in Enumerable&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; Enumerable&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;从代码我们的输出我们可以知道，&lt;code&gt;included&lt;/code&gt;类方法作用域&lt;code&gt;self&lt;/code&gt;为&lt;code&gt;Module A&lt;/code&gt;，并传入&lt;code&gt;include A&lt;/code&gt;的&lt;code&gt;receiver Enumerable&lt;/code&gt;。然后我们再看看例子七，结合&lt;code&gt;extend&lt;/code&gt;与&lt;code&gt;include&lt;/code&gt;的理解，就能明白其中的原理所在。&lt;/p&gt;

&lt;p&gt;再来看看 ActiveSupport::Concern 的实现：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;在没有引入&lt;code&gt;ActiveSupport::Concern&lt;/code&gt;之前，我们可以这样进行模块分离&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;M&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;included&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;extend&lt;/span&gt; &lt;span class="no"&gt;ClassMethods&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;class_eval&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;scope&lt;/span&gt; &lt;span class="ss"&gt;:disabled&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="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;disabled: &lt;/span&gt;&lt;span class="kp"&gt;true&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="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;InstanceMethods&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;ClassMethods&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;say_hello&lt;/span&gt;
      &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"say hello"&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;module&lt;/span&gt; &lt;span class="nn"&gt;InstanceMethods&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;say_no&lt;/span&gt;
      &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"say no"&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;从代码可知，通过&lt;code&gt;extend&lt;/code&gt;和&lt;code&gt;class_eval&lt;/code&gt;为&lt;code&gt;base&lt;/code&gt;定义了&lt;code&gt;ClassMethods&lt;/code&gt;里面的类方法，通过&lt;code&gt;include&lt;/code&gt; 为&lt;code&gt;base&lt;/code&gt;定义了&lt;code&gt;InstanceMethods&lt;/code&gt;里面的实力方法。&lt;/p&gt;

&lt;p&gt;当我们引入&lt;code&gt;ActiveSupport::Concern&lt;/code&gt;之后，以上例子我们可以这样写：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'active_support/concern'&lt;/span&gt;

&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;M&lt;/span&gt;
  &lt;span class="kp"&gt;extend&lt;/span&gt; &lt;span class="no"&gt;ActiveSupport&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Concern&lt;/span&gt;

  &lt;span class="n"&gt;included&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;scope&lt;/span&gt; &lt;span class="ss"&gt;:disabled&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="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;disabled: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;InstanceMethods&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;ClassMethods&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;say_hello&lt;/span&gt;
      &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"say hello"&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;module&lt;/span&gt; &lt;span class="nn"&gt;InstanceMethods&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;say_no&lt;/span&gt;
      &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"say no"&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;最后，我们再来看看&lt;a href="https://github.com/rails/rails/blob/master/activesupport/lib/active_support/concern.rb" rel="nofollow" target="_blank" title=""&gt;ActiveSupport::Concern&lt;/a&gt;,是不是就很好理解了？&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Concern&lt;/span&gt;
    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MultipleIncludedBlocks&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;StandardError&lt;/span&gt; &lt;span class="c1"&gt;#:nodoc:&lt;/span&gt;
      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;
        &lt;span class="k"&gt;super&lt;/span&gt; &lt;span class="s2"&gt;"Cannot define multiple 'included' blocks for a Concern"&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;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;extended&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="c1"&gt;#:nodoc:&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;instance_variable_set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:@_dependencies&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;append_features&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="k"&gt;if&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;instance_variable_defined?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:@_dependencies&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;instance_variable_get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:@_dependencies&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
      &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;
        &lt;span class="vi"&gt;@_dependencies.each&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;dep&lt;/span&gt;&lt;span class="o"&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;include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dep&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;super&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;extend&lt;/span&gt; &lt;span class="nb"&gt;const_get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:ClassMethods&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;const_defined?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:ClassMethods&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;class_eval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="vi"&gt;@_included_block&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;instance_variable_defined?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:@_included_block&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;def&lt;/span&gt; &lt;span class="nf"&gt;included&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;block&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;base&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;nil?&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="no"&gt;MultipleIncludedBlocks&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;instance_variable_defined?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:@_included_block&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="vi"&gt;@_included_block&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;block&lt;/span&gt;
      &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="k"&gt;super&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;def&lt;/span&gt; &lt;span class="nf"&gt;class_methods&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;class_methods_module_definition&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;mod&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;const_defined?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:ClassMethods&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt;
        &lt;span class="nb"&gt;const_get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:ClassMethods&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nb"&gt;const_set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:ClassMethods&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

      &lt;span class="n"&gt;mod&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;module_eval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;class_methods_module_definition&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;/code&gt;&lt;/pre&gt;
&lt;p&gt;Rails4.1 之后，Module 还加入了&lt;a href="http://api.rubyonrails.org/v4.1.0/classes/Module/Concerning.html" rel="nofollow" target="_blank" title=""&gt;Concerning&lt;/a&gt;方法&lt;/p&gt;
&lt;h2 id="Concerning"&gt;Concerning&lt;/h2&gt;
&lt;p&gt;我们先来看看细化 concern 的几种方法&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;通过注释&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Todo&lt;/span&gt;
  &lt;span class="c1"&gt;# Other todo implementation&lt;/span&gt;
  &lt;span class="c1"&gt;# ...&lt;/span&gt;

  &lt;span class="c1"&gt;## Event tracking&lt;/span&gt;
  &lt;span class="n"&gt;has_many&lt;/span&gt; &lt;span class="ss"&gt;:events&lt;/span&gt;

  &lt;span class="n"&gt;before_create&lt;/span&gt; &lt;span class="ss"&gt;:track_creation&lt;/span&gt;
  &lt;span class="n"&gt;after_destroy&lt;/span&gt; &lt;span class="ss"&gt;:track_deletion&lt;/span&gt;

  &lt;span class="kp"&gt;private&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;track_creation&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;ul&gt;
&lt;li&gt;通过&lt;code&gt;ActiveSupport::Concern&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Todo&lt;/span&gt;
  &lt;span class="c1"&gt;# Other todo implementation&lt;/span&gt;
  &lt;span class="c1"&gt;# ...&lt;/span&gt;

  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;EventTracking&lt;/span&gt;
    &lt;span class="kp"&gt;extend&lt;/span&gt; &lt;span class="no"&gt;ActiveSupport&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Concern&lt;/span&gt;

    &lt;span class="n"&gt;included&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;has_many&lt;/span&gt; &lt;span class="ss"&gt;:events&lt;/span&gt;
      &lt;span class="n"&gt;before_create&lt;/span&gt; &lt;span class="ss"&gt;:track_creation&lt;/span&gt;
      &lt;span class="n"&gt;after_destroy&lt;/span&gt; &lt;span class="ss"&gt;:track_deletion&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="kp"&gt;private&lt;/span&gt;
      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;track_creation&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;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;EventTracking&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;通过&lt;code&gt;concerning&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Todo&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;
  &lt;span class="c1"&gt;# Other todo implementation&lt;/span&gt;
  &lt;span class="c1"&gt;# ...&lt;/span&gt;

  &lt;span class="n"&gt;concerning&lt;/span&gt; &lt;span class="ss"&gt;:EventTracking&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;included&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;has_many&lt;/span&gt; &lt;span class="ss"&gt;:events&lt;/span&gt;
      &lt;span class="n"&gt;before_create&lt;/span&gt; &lt;span class="ss"&gt;:track_creation&lt;/span&gt;
      &lt;span class="n"&gt;after_destroy&lt;/span&gt; &lt;span class="ss"&gt;:track_deletion&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="kp"&gt;private&lt;/span&gt;
      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;track_creation&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;span class="k"&gt;end&lt;/span&gt;

&lt;span class="no"&gt;Todo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ancestors&lt;/span&gt;
&lt;span class="c1"&gt;# [Todo,Todo::EventTracking,...]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;总得来说，&lt;code&gt;concerning&lt;/code&gt;主要用于切分比较小的 model
另外，还有还提供了类似的&lt;code&gt;concern&lt;/code&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;:EventTracking&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;equivalent&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt;

&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;EventTracking&lt;/span&gt;
  &lt;span class="kp"&gt;extend&lt;/span&gt; &lt;span class="no"&gt;ActiveSupport&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Concern&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;最后贴上自用 &lt;a href="https://gist.github.com/Justin-lu/156bd4a1cba1c507e485" rel="nofollow" target="_blank" title=""&gt;sublime snippet&lt;/a&gt;,但是我是 Vim 党。&lt;/p&gt;

&lt;p&gt;Reference:
&lt;a href="http://www.railstips.org/blog/archives/2009/05/15/include-vs-extend-in-ruby/" rel="nofollow" target="_blank"&gt;http://www.railstips.org/blog/archives/2009/05/15/include-vs-extend-in-ruby/&lt;/a&gt;
&lt;a href="https://github.com/rails/rails/blob/master/activesupport/lib/active_support/concern.rb" rel="nofollow" target="_blank"&gt;https://github.com/rails/rails/blob/master/activesupport/lib/active_support/concern.rb&lt;/a&gt;
&lt;a href="https://github.com/rails/rails/blob/master/activesupport/lib/active_support/concern.rb" rel="nofollow" target="_blank"&gt;https://github.com/rails/rails/blob/master/activesupport/lib/active_support/concern.rb&lt;/a&gt;&lt;/p&gt;

&lt;hr&gt;

&lt;p&gt;补充：&lt;/p&gt;
&lt;h2 id="ActiveSupport::Concern#append_features"&gt;ActiveSupport::Concern#append_features&lt;/h2&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;append_features&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="k"&gt;if&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;instance_variable_defined?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:@_dependencies&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;instance_variable_get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:@_dependencies&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;
    &lt;span class="vi"&gt;@_dependencies.each&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;dep&lt;/span&gt;&lt;span class="o"&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;include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dep&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;super&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;extend&lt;/span&gt; &lt;span class="nb"&gt;const_get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:ClassMethods&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;const_defined?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:ClassMethods&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;class_eval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="vi"&gt;@_included_block&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;instance_variable_defined?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:@_included_block&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;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;append_features&lt;/code&gt;也是 module 的一个 callback，会在 include 之后，为当前 class 添加 module 的变量，常量，方法等。append_features 会先与 included 被调用，详见：&lt;a href="http://apidock.com/ruby/Module/append_features" rel="nofollow" target="_blank" title=""&gt;append_features&lt;/a&gt;
上面的代码中，如&lt;a href="/neverlandxy_naix" class="user-mention" title="@neverlandxy_naix"&gt;&lt;i&gt;@&lt;/i&gt;neverlandxy_naix&lt;/a&gt;所说的一样，正是通过递归的方法处理多重嵌套&lt;/p&gt;

&lt;p&gt;首先看到一个&lt;code&gt;if&lt;/code&gt;判断，这里判断当前类 (base) 是否定义了&lt;code&gt;@_dependencies&lt;/code&gt;，如果被定义，则把当前 module 加入&lt;code&gt;@_dependencies&lt;/code&gt;。怎么说呢？我们再来看看&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;extended&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="c1"&gt;#:nodoc:&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;instance_variable_set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:@_dependencies&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;extended&lt;/code&gt;类似于&lt;code&gt;included&lt;/code&gt;,具体用法见&lt;a href="http://ruby-doc.org/core-2.2.0/Module.html#method-i-extended" rel="nofollow" target="_blank" title=""&gt;extended&lt;/a&gt;
看完&lt;code&gt;extended&lt;/code&gt;的用法，我们知道，如果当前类&lt;code&gt;extend&lt;/code&gt;了&lt;code&gt;ActiveSupport::Concern&lt;/code&gt;,则&lt;code&gt;@_dependencies&lt;/code&gt;会被定义。&lt;/p&gt;

&lt;p&gt;第二个 if 判断，判断当前类是否继承于当前模块，如果是，则不需要做其他操作，如果不是，则说明当前类既不是当前模块的子类，也没有&lt;code&gt;extend&lt;/code&gt; &lt;code&gt;ActiveSupport::Concern&lt;/code&gt;。也就是我们最终要&lt;code&gt;include&lt;/code&gt;当前模块的类，此时，当前类&lt;code&gt;include&lt;/code&gt;当前模块所有依赖&lt;code&gt;@_dependencies&lt;/code&gt;,并定义&lt;code&gt;ClassMethods&lt;/code&gt;和&lt;code&gt;included&lt;/code&gt;block 里面的方法。&lt;/p&gt;</description>
      <author>justin</author>
      <pubDate>Sat, 27 Jun 2015 14:50:16 +0800</pubDate>
      <link>https://ruby-china.org/topics/26208</link>
      <guid>https://ruby-china.org/topics/26208</guid>
    </item>
    <item>
      <title>Rails Activerecod callback 问题</title>
      <description>&lt;p&gt;请问，什么回调函数，
能实现我每次做 where 查询之前都先执行一次特定函数。（类似&lt;code&gt;after_find&lt;/code&gt;）
或者，能够实现每天执行一次。&lt;/p&gt;

&lt;p&gt;希望各位大牛帮帮忙，google 找不到
感激不尽！&lt;/p&gt;</description>
      <author>justin</author>
      <pubDate>Mon, 30 Sep 2013 16:45:13 +0800</pubDate>
      <link>https://ruby-china.org/topics/14490</link>
      <guid>https://ruby-china.org/topics/14490</guid>
    </item>
    <item>
      <title>如何合并两个 ActiveRecord::Relation 的结果集</title>
      <description>&lt;p&gt;请教下大家一个问题，现在因为使用 ransack 这个 Gem，使用 search 查询功能时，要求对象必须是 ActiveRecord::Relation 如&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;SampleOrder&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;:id&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
&lt;span class="n"&gt;second&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;SampleOrder&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;:id&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;想要的结果是 result ＝ first + second 且 result.class =&amp;gt; ActiveRecord::Relation&lt;/p&gt;

&lt;p&gt;望各位大神指点迷津！&lt;/p&gt;</description>
      <author>justin</author>
      <pubDate>Sun, 12 May 2013 22:27:28 +0800</pubDate>
      <link>https://ruby-china.org/topics/10928</link>
      <guid>https://ruby-china.org/topics/10928</guid>
    </item>
    <item>
      <title>请教关于 Git 工作流的问题</title>
      <description>&lt;p&gt;请教各位使用 git 版本管理的程序猿：
多人开发不同模块下，有什么比较好的工作流程。
目前使用的是（6 个人开发），不同模块在不同分支开发，master 分支上修改共用代码，模块分支不断更新 master 分支代码，直到模块分支开发完成，在合并到 master 分支。
现在遇到这样的问题：就是在合并模块分支到 master 分支时，会出现比较多的冲突，而且有些是之前就改过的。&lt;/p&gt;

&lt;p&gt;不知道我是否描述清楚。&lt;/p&gt;</description>
      <author>justin</author>
      <pubDate>Sat, 23 Mar 2013 21:14:52 +0800</pubDate>
      <link>https://ruby-china.org/topics/9703</link>
      <guid>https://ruby-china.org/topics/9703</guid>
    </item>
  </channel>
</rss>
