<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>WinstonYW</title>
    <description>This is the blog of Winston Teo Yong Wei. Mostly about Ruby and the Community.</description>
    <link>http://winstonyw.com</link>
    <atom:link href="http://winstonyw.com/feed.xml" rel="self" type="application/rss+xml" />
    
    <item>
      <title>Responsible Engineering</title>
      <description>&lt;p&gt;I wrote a post originally to talk about &quot;Responsible Engineering&quot; and showed it to folks at Jolly Good Code for feedback. Then Choon Keat showed me this particular set of slides..&lt;/p&gt;

&lt;p&gt;After going through the slides, I decided that my post wasn&#39;t worth reading and you &lt;a href=&quot;https://speakerdeck.com/mcfunley/choose-boring-technology&quot;&gt;should read that set of slides&lt;/a&gt; instead.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://twitter.com/mcfunley&quot;&gt;Dan McKinley&lt;/a&gt; covered everything I wanted to say about being responsible and more in his &lt;a href=&quot;https://www.youtube.com/watch?v=wUmx-dlYS34&quot;&gt;talk titled &quot;Choose Boring Technology&quot;&lt;/a&gt;. The deck is golden and every engineer should read and memorize it.&lt;/p&gt;

&lt;p&gt;Also, there are some &lt;a href=&quot;https://twitter.com/mcfunley/status/582557375845941248&quot;&gt;interesting conversations on Twitter too&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;del&gt;The only thing I would add is that IF anyone still decides to try out that new shiny thing on production, please, please insist for it to be tested. Any kind of tests!&lt;/del&gt;&lt;/p&gt;

&lt;p&gt;Scrap that.&lt;/p&gt;

&lt;p&gt;Even writing tests is not justification enough to introduce a new shiny thing to the mix.
Does the app really need that to work, or was it added to satisfy your own personal desire?
Think of the big picture and the impact that the new shiny thing would bring to the team.
Would that be a positive or negative impact? Brings to mind &lt;a href=&quot;http://dmathieu.com/articles/development/ember-rails/&quot;&gt;this little story&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Maybe a responsible engineer is more likely to stick with &quot;boring&quot; technology?&lt;/p&gt;
</description>
      <pubDate>Sat, 17 Oct 2015 00:00:00 +0800</pubDate>
      <link>http://winstonyw.com/2015/10/17/responsible_engineering/</link>
      <guid isPermaLink="true">http://winstonyw.com/2015/10/17/responsible_engineering/</guid>
    </item>
    
    <item>
      <title>Half A Decade Of RedDotRubyConf</title>
      <description>&lt;p&gt;This year, 2015, is the fifth run of RDRC and my third time organising it.
Even though it&#39;s my third time doing this, it&#39;s not in anyway easier
because expectations have definitely gone up over the years,
and I have to do something about the feedback collected last year. :)&lt;/p&gt;

&lt;p&gt;The preparation started 6 months before the conference, and it always begin with the venue and dates.
I picked Biopolis again because it&#39;s really affordable, and that means ticket prices can stay similar.&lt;/p&gt;

&lt;p&gt;Then I started to invite several key speakers, one of whom is Matz.
I really wanted to have Matz at RedDotRubyConf 2015,
as he was here in 2011 and so I thought it would be special to have him back again 4 years later.
But alas! Matz wasn&#39;t able  make it for the dates (May 28, 29) which I planned for.. What? OMG!&lt;/p&gt;

&lt;p&gt;Like I said, I really, really wanted to have Matz at RedDotRubyConf 2015!
So I went back to the venue and asked for a few other open dates
and luckily one of it suited Matz&#39;s schedule. Phew!
And the rest was history as Aaron, Sam, Linda, Laurent and Jesse all agreed to come too!&lt;/p&gt;

&lt;p&gt;From January onwards, the months went by quickly as we took care of the logistical challenges of the conference.
Too much to say here, but did I mention I am trying to write an open source Conference Planning Guide?&lt;/p&gt;

&lt;p&gt;Finally June 4, 5 came and went by quickly and I really couldn&#39;t have done it without the help of
&lt;a href=&quot;https://twitter.com/tgx_world&quot;&gt;Guo Xiang&lt;/a&gt;,
&lt;a href=&quot;https://twitter.com/jin_&quot;&gt;Jingwen&lt;/a&gt;,
&lt;a href=&quot;https://twitter.com/elishatan&quot;&gt;Elisha&lt;/a&gt;,
&lt;a href=&quot;https://twitter.com/anna_fil&quot;&gt;Anna&lt;/a&gt;,
&lt;a href=&quot;https://twitter.com/laurenceputra&quot;&gt;Laurence&lt;/a&gt; and
&lt;a href=&quot;https://twitter.com/cheeaun&quot;&gt;Cheeaun&lt;/a&gt;.
They covered the grounds that I wasn&#39;t able to attend to and were instrumental in making the conference a success.
Thank you!&lt;/p&gt;

&lt;h2&gt;Thank You Sponsors!&lt;/h2&gt;

&lt;p&gt;Our sponsors were awesome and I can&#39;t thank them enough!
They just wanted to do their bit to help build the Ruby community
and I hope RDRC helped them snag a few more deals or new hires!&lt;/p&gt;

&lt;p&gt;Why are sponsorships important?&lt;/p&gt;

&lt;p&gt;Firstly, sponsorships are boosts of confidence for what we were doing,
such that organisations find it advantageous for them to be a sponsor.&lt;/p&gt;

&lt;p&gt;Secondly, because ticket sales alone are never enough to cover the full cost of the conference,
and so sponsorships are really important to make sure we don&#39;t go into red.&lt;/p&gt;

&lt;p&gt;Thank you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.pocketmath.com/&quot;&gt;PocketMath&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://piktochart.com/&quot;&gt;Piktochart&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.paypal.com&quot;&gt;Braintree Paypal&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://flowhero.io/&quot;&gt;Flowhero.io&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.opsmanager.com/&quot;&gt;OpsManager&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.tinkerbox.com.sg/&quot;&gt;Tinkerbox&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/&quot;&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.thoughtworks.com/&quot;&gt;ThoughtWorks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.digitalocean.com/&quot;&gt;DigitalOcean&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.stickermule.com/&quot;&gt;Stickermule&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pragprog.com/&quot;&gt;The Pragmatic Bookshelf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.ida.gov.sg/&quot;&gt;IDA Labs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;Thank You Speakers&lt;/h2&gt;

&lt;p&gt;Speakers - They are the soul of the conference. Thank you all so much!&lt;/p&gt;

&lt;p&gt;25 Speakers - 6 Key Notes, 9 CFPs and 9 Lightning Talks.&lt;/p&gt;

&lt;p&gt;We had topics about Ruby (and mRuby), Rails, RubyMotion, Robotics,
Security, Refactoring, Optimization, Open Source, etc,
and this year, we also did a Panel discussion on Ruby
which was very well-received!&lt;/p&gt;

&lt;p&gt;I learned a lot from all the talks and I hope you do too.
You can enjoy the talks again as
&lt;a href=&quot;https://www.youtube.com/playlist?list=PLE7tQUdRKcyZdMYKatu_nics8Pkjxl3-F&quot;&gt;they are now available on Confreaks&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thank you Matz, Aaron, Sam, Linda, Laurent, Jesse, Aman,
André, Sau Sheong, Shipeng, Prathamesh, Laura, Juanito, Hiroaki, Christopher, Joy, Vaidehi,
Paolo, Hiroshi, Tania, Guo Xiang, Radamanthus, Elisha, Grzegorz, Tomoya and Yuki!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/rdrc15-speakers.jpg&quot; alt=&quot;Speakers&quot; /&gt;&lt;/p&gt;

&lt;h2&gt;Thank YOU!!!&lt;/h2&gt;

&lt;p&gt;As I have always said, RDRC is for you, and you, and you!&lt;/p&gt;

&lt;p&gt;Almost 350 Rubyists from all over the World gathered together for 2-days
to celebrate Ruby on the tiny island called Singapore.&lt;/p&gt;

&lt;p&gt;Thank you for making this possible. Thank you all for your support!&lt;/p&gt;

&lt;p&gt;Let&#39;s continue to make the Ruby community even better!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/rdrc15-attendees.jpg&quot; alt=&quot;Attendees&quot; /&gt;&lt;/p&gt;

&lt;h2&gt;Infographics&lt;/h2&gt;

&lt;p&gt;Powered by &lt;a href=&quot;http://piktochart.com/&quot;&gt;Piktochart&lt;/a&gt;, one of our sponsors.&lt;/p&gt;

&lt;p&gt;Piktochart made generating this infographic enjoyable and truly A BREEZE!!!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/rdrc15-infographics.jpg&quot; alt=&quot;Infographics&quot; /&gt;&lt;/p&gt;

&lt;h2&gt;Resources&lt;/h2&gt;

&lt;p&gt;Just refer to &lt;a href=&quot;https://gist.github.com/cheeaun/2b6a985d65093b4b1a3d&quot;&gt;Cheeaun&#39;s awesome curated list&lt;/a&gt;!&lt;/p&gt;

&lt;h2&gt;Closing&lt;/h2&gt;

&lt;p&gt;Honestly, imo, I felt that this was the best RDRC amongst that last 3 that I organised.
First year was about making sure I don&#39;t mess up and that the brand continued to grow.
Second year was about repeating the same feat (while juggling with &lt;a href=&quot;http://www.jollygoodcode.com/&quot;&gt;starting my own consultancy&lt;/a&gt;).
This year, it was about taking care of the finer details, so that everyone felt welcomed.&lt;/p&gt;

&lt;p&gt;Things that I felt we did well:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We have private buses that brought speakers (who were staying at the conference hotel) to Biopolis&lt;/li&gt;
&lt;li&gt;We have better breakfasts and tea breaks&lt;/li&gt;
&lt;li&gt;We have barista-style coffee/tea because developers care for their daily fix&lt;/li&gt;
&lt;li&gt;We have vegetarian lunch boxes for attendees who indicated on registration that they were vegetarian&lt;/li&gt;
&lt;li&gt;We have cleaners to make sure the venue is kept spick and span&lt;/li&gt;
&lt;li&gt;We did a RubyMotion workshop before the conference, and RailsGirls and Git Workshop after the conference&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;If I were to give RDRC 2015 a score, I would say we scored 90 marks. Haha.&lt;/p&gt;

&lt;p&gt;Organising a conference is challenging and tiring, but at the same time, fun and rewarding.&lt;/p&gt;

&lt;p&gt;That&#39;s all folks! :)&lt;/p&gt;

&lt;p&gt;Drop me an email - suggestions, compliments or criticisms. Thank you!&lt;/p&gt;
</description>
      <pubDate>Thu, 30 Jul 2015 00:00:00 +0800</pubDate>
      <link>http://winstonyw.com/2015/07/30/half_a_decade_of_reddotrubyconf/</link>
      <guid isPermaLink="true">http://winstonyw.com/2015/07/30/half_a_decade_of_reddotrubyconf/</guid>
    </item>
    
    <item>
      <title>Setting Up Ruby on Rails On Digital Ocean</title>
      <description>&lt;p&gt;&lt;strong&gt;Edit&lt;/strong&gt; This has been updated for Ubuntu 14.10, Ruby 2.2.2 and Postgres 9.4.&lt;/p&gt;

&lt;p&gt;Documentation of how I setup &lt;a href=&quot;http://www.sgbusfeedback.com&quot;&gt;SGBusFeedback.com&lt;/a&gt;,
a basic Ruby on Rails application backed by a PostgreSQL database on Digital Ocean.&lt;/p&gt;

&lt;p&gt;Noting it down for my future self.&lt;/p&gt;

&lt;h2&gt;Create Droplet on Digital Ocean&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Login to Digital Ocean and start &lt;code&gt;Create&lt;/code&gt;-ing a Droplet&lt;/li&gt;
&lt;li&gt;Size      : $5/mth&lt;/li&gt;
&lt;li&gt;Region    : Singapore&lt;/li&gt;
&lt;li&gt;Image     : Linux Distribtions &gt; Ubuntu 14.04 x64&lt;/li&gt;
&lt;li&gt;Add SSH key for easy access to the Droplet&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Create Droplet&lt;/code&gt;!&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;Set Up Droplet&lt;/h2&gt;

&lt;p&gt;Assuming that your SSH key has been set up properly, SSH into your Droplet.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;machine$&amp;gt; ssh root@&amp;lt;ipaddress&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Add a Deploy User&lt;/h3&gt;

&lt;p&gt;Create a &lt;code&gt;deploy&lt;/code&gt; user on the Droplet.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;droplet$&amp;gt; sudo adduser deploy
droplet$&amp;gt; sudo adduser deploy sudo #add to sudo group
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Create a SSH key on your machine, and upload the key.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;machine$&amp;gt; ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/winston/.ssh/id_rsa): id_deploy_digital_ocean
...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Copy the SSH key to the Droplet.&lt;/p&gt;

&lt;p&gt;On Mac? &lt;code&gt;brew install ssh-copy-id&lt;/code&gt;. On Linux? You already have &lt;code&gt;ssh-copy-id&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;machine$&amp;gt; ssh-copy-id -i ~/.ssh/id_deploy_digital_ocean deploy@&amp;lt;ipaddress&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now you can login to your Droplet with:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;machine$&amp;gt; ssh-add ~/.ssh/id_deploy_digital_ocean
machine$&amp;gt; ssh deploy@&amp;lt;ipaddress&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Harden Droplet&lt;/h3&gt;

&lt;p&gt;Modify SSH settings &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt; in the Droplet.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add &lt;code&gt;PermitRootLogin without-password&lt;/code&gt; (&lt;a href=&quot;http://askubuntu.com/questions/449364/what-does-without-password-mean-in-sshd-config-file&quot;&gt;What?&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Add &lt;code&gt;UseDNS no&lt;/code&gt; (&lt;a href=&quot;http://unix.stackexchange.com/questions/56941/what-is-the-point-of-sshd-usedns-option&quot;&gt;What?&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Change &lt;code&gt;Port&lt;/code&gt; to something unique and take note. E.g. &lt;code&gt;8888&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Reload SSH with &lt;code&gt;reload ssh&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Verify your SSH settings with your new user. In a new Terminal:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;machine$&amp;gt; ssh -p 8888 deploy@&amp;lt;ipaddress&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Bonus. Add this to &lt;code&gt;~/.ssh/config&lt;/code&gt; on your machine so that login will be a breeze.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# in ~/.ssh/config
Host    &amp;lt;appname&amp;gt;
    HostName        &amp;lt;ipaddress&amp;gt;
    Port            8888
    User            deploy
    IdentityFile    ~/.ssh/id_deploy_digital_ocean
&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code&gt;machine$&amp;gt; ssh &amp;lt;appname&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Update and Upgrade Ubuntu&lt;/h3&gt;

&lt;p&gt;A Ruby on Rails server requires quite a few things. Installed these as the &lt;code&gt;deploy&lt;/code&gt; user.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;droplet$&amp;gt; sudo apt-get update
droplet$&amp;gt; sudo apt-get upgrade
droplet$&amp;gt; sudo apt-get install git-core
droplet$&amp;gt; sudo apt-get install nodejs # for assets compilation.
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;RVM&lt;/h3&gt;

&lt;p&gt;Install RVM.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;droplet$&amp;gt; curl -L https://get.rvm.io | bash -s stable
# If an error about gpg occurs, follow the instructions..
droplet$&amp;gt; gpg --keyserver hkp://keys.gnupg.net --recv-keys D39DC0E3
# https://github.com/wayneeseguin/rvm/issues/3110
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Relogin to shell, install RVM requirements, and Ruby.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;droplet$&amp;gt; source /etc/profile.d/rvm.sh
droplet$&amp;gt; echo &quot;source /etc/profile.d/rvm.sh&quot; &amp;gt;&amp;gt; ~/.bashrc
droplet$&amp;gt; rvm requirements
droplet$&amp;gt; rvm install 2.2.2
droplet$&amp;gt; rvm use 2.2.2 --default
droplet$&amp;gt; ruby -v
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;RubyGems Setup&lt;/h3&gt;

&lt;p&gt;Prevent RubyGems from installing docs.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;droplet$&amp;gt; echo &quot;gem: --no-ri --no-rdoc&quot; &amp;gt; ~/.gemrc
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Install Nginx and Passenger&lt;/h3&gt;

&lt;p&gt;Follow the instructions on the &lt;a href=&quot;https://www.phusionpassenger.com/documentation/Users%20guide%20Nginx.html#installation&quot;&gt;Official Documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;Condensed Version:&lt;/h4&gt;

&lt;p&gt;Install Phusion&#39;s PGP key and add HTTPS support for ATP.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;droplet$&amp;gt; sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 561F9B9CAC40B2F7
droplet$&amp;gt; sudo apt-get install apt-transport-https ca-certificates
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Add Passenger&#39;s repository. &lt;em&gt;&lt;strong&gt;Just one.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;droplet$&amp;gt; sudo sh -c &#39;echo &quot;deb https://oss-binaries.phusionpassenger.com/apt/passenger trusty main&quot; &amp;gt;&amp;gt; /etc/apt/sources.list.d/passenger.list&#39;
droplet$&amp;gt; sudo chown root: /etc/apt/sources.list.d/passenger.list
droplet$&amp;gt; sudo chmod 600 /etc/apt/sources.list.d/passenger.list
droplet$&amp;gt; sudo apt-get update
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Install Nginx and Passenger packages.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# The Official Documentation uses `nginx-extras` but `nginx-full` is good enough.
droplet$&amp;gt; sudo apt-get install nginx-full passenger
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Edit &lt;code&gt;/etc/nginx/nginx.conf&lt;/code&gt; and uncomment &lt;code&gt;passenger_root&lt;/code&gt; and &lt;code&gt;passenger_ruby&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Also find out where your &lt;code&gt;ruby&lt;/code&gt; is, and use that for &lt;code&gt;passenger_ruby&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;droplet$&amp;gt; passenger-config --ruby-command
  Command: /usr/local/rvm/gems/ruby-2.2.2/wrappers/ruby
  Version: ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-linux]
  To use in Apache: PassengerRuby /usr/local/rvm/gems/ruby-2.2.2/wrappers/ruby
  To use in Nginx : passenger_ruby /usr/local/rvm/gems/ruby-2.2.2/wrappers/ruby
  To use with Standalone: /usr/local/rvm/gems/ruby-2.2.2/wrappers/ruby /usr/bin/passenger start
&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code&gt;droplet$&amp;gt; sudo vi /etc/nginx/nginx.conf
... Edits ..
droplet$&amp;gt; sudo service nginx restart
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Install PostgreSQL&lt;/h3&gt;

&lt;p&gt;Install it.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;droplet$&amp;gt; sudo apt-get install postgresql-9.4 libpq-dev
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Set up Postgres user.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;password&lt;/code&gt; that you used here will be used in your app&#39;s &lt;code&gt;database.yml&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;droplet$&amp;gt; sudo su - postgres
droplet$&amp;gt; psql -c&quot;alter user postgres with password &#39;strong123password&#39;;&quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Create the Production database.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;droplet$&amp;gt; psql
psql&amp;gt; create database &amp;lt;production_dbname&amp;gt;;
psql&amp;gt; exit
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Connect GitHub Repo to Droplet&lt;/h3&gt;

&lt;p&gt;Create a SSH key on the Droplet, and then add it to the GitHub repo.&lt;/p&gt;

&lt;p&gt;Follow the instructions here: &lt;a href=&quot;https://help.github.com/articles/generating-ssh-keys/&quot;&gt;https://help.github.com/articles/generating-ssh-keys/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Make sure you run this &lt;code&gt;droplet$&amp;gt; ssh -T git@github.com&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This will ensure that Mina can deploy with GitHub.&lt;/p&gt;

&lt;h3&gt;Setup Mina&lt;/h3&gt;

&lt;p&gt;Follow the instructions on &lt;a href=&quot;https://github.com/mina-deploy/mina&quot;&gt;Mina&#39;s README&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;Condensed Version:&lt;/h4&gt;

&lt;p&gt;Init Mina on your application.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;machine$&amp;gt; mina init
Created config/deploy.rb.
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Use &lt;code&gt;rvm&lt;/code&gt; or &lt;code&gt;rbenv&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require &#39;mina/rvm&#39;
# require &#39;mina/rbenv&#39;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Update &lt;code&gt;config/deploy.rb&lt;/code&gt; with Droplet&#39;s Details.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;set :domain,       &amp;lt;ipaddress&amp;gt;
set :deploy_to,   &#39;/home/deploy/&amp;lt;app_domain&#39;
set :repository,  &#39;git@github.com:&amp;lt;user&amp;gt;/&amp;lt;repo&amp;gt;.git&#39;
set :branch,      &#39;master&#39;
set :user,        &#39;deploy&#39;
set :port,        &#39;8888&#39;
....
task :environment do
  queue &#39;source ~/.bash_profile&#39;

  # For those using RVM, use this to load an RVM version@gemset.
  invoke :&#39;rvm:use[ruby-2.1.4]&#39;
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;SetUp Mina on Droplet.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;machine$&amp;gt; mina setup
-----&amp;gt; Using RVM environment &#39;ruby-2.1.4&#39;
       Using /home/demo/.rvm/gems/ruby-2.1.4
-----&amp;gt; Setting up /home/deploy/&amp;lt;app_domain&amp;gt;

       total 16
       drwxrwxr-x 4 deploy deploy 4096 Nov  5 02:00 .
       drwxr-xr-x 8 deploy deploy 4096 Nov  5 02:00 ..
       drwxrwxr-x 2 deploy deploy 4096 Nov  5 02:00 releases
       drwxrwxr-x 4 deploy deploy 4096 Nov  5 02:00 shared

-----&amp;gt; Done.
-----&amp;gt; Be sure to edit &#39;shared/config/database.yml&#39;.
-----&amp;gt; Be sure to edit &#39;shared/config/secrets.yml&#39;.
       Elapsed time: 1.00 seconds
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Important!&lt;/strong&gt;&lt;/em&gt; Update &lt;code&gt;shared/config/database.yml&lt;/code&gt; and &lt;code&gt;shared/config/secrets.yml&lt;/code&gt; on the Droplet.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#database.yml
production:
    adapter: postgresql
    encoding: unicode
    database: &amp;lt;production_dbname&amp;gt;
    username: postgres
    password: strong123password
    host: localhost
&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code&gt;#secrets.yml
production:
    secret_key_base: &amp;lt;Generated from `rake secret`&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You might also need these settings in &lt;code&gt;.bash_profile&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# vi .bash_profile
export LANGUAGE=en_US.UTF-8
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now, you can deploy your application to the Droplet.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;machine$&amp;gt; mina deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Update Nginx Configuration&lt;/h3&gt;

&lt;p&gt;Update the file &lt;code&gt;/etc/nginx/sites-enabled/default&lt;/code&gt; with these settings:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;server {
    listen 80 default_server;
    listen [::]:80 default_server ipv6only=on;

    server_name         &amp;lt;app_domain&amp;gt;;
    passenger_enabled   on;
    rails_env           production;
    root                /home/deploy/&amp;lt;app_domain&amp;gt;/current/public;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Restart the Nginx server, you should be able to see your app at the &lt;code&gt;ipaddress&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;droplet$&amp;gt; sudo service nginx restart
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Next Steps&lt;/h3&gt;

&lt;p&gt;At this point, you already have your app up and running at &lt;code&gt;ipaddress&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You will probably need to do the following to make it work nicely:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;figaro&lt;/code&gt; or add ENV variables to &lt;code&gt;.bash_profile&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Point DNS to the &lt;code&gt;ipaddress&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Explore other configurations for your Nginx (static 40&lt;em&gt; or 50&lt;/em&gt;)&lt;/li&gt;
&lt;li&gt;Put in place backup strategies for your PostgreSQL (maybe use RDS instead?)&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;That&#39;s it!&lt;/p&gt;

&lt;h3&gt;Troubleshooting&lt;/h3&gt;

&lt;p&gt;Sometimes, the $5/mth Droplet might complain of inadequate swap space. &lt;a href=&quot;https://www.digitalocean.com/community/tutorials/how-to-add-swap-on-ubuntu-12-04&quot;&gt;Read this&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Also, Nginx error logs are pretty handy. Available at &lt;code&gt;/var/log/nginx/error.log&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;Resources&lt;/h2&gt;

&lt;p&gt;Reading these really helped!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-12-04&quot;&gt;Initial Server Setup with Ubuntu 12.04&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://gorails.com/deploy/ubuntu/14.04&quot;&gt;Deploy Ruby On Rails on Ubuntu 14.04 Trusty Tahr&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://gist.github.com/sathishmanohar/5491263&quot;&gt;https://gist.github.com/sathishmanohar/5491263&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://voiceofchunk.com/2014/06/09/deploying-rails-apps-using-passenger-rbenv-postgresql-and-mina/&quot;&gt;Deploying a Rails app on Ubuntu 14.04 - Passenger, RBenv, PostgreSQL, and Mina&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <pubDate>Fri, 24 Oct 2014 00:00:00 +0800</pubDate>
      <link>http://winstonyw.com/2014/10/24/setting_up_ruby_on_rails_on_digital_ocean/</link>
      <guid isPermaLink="true">http://winstonyw.com/2014/10/24/setting_up_ruby_on_rails_on_digital_ocean/</guid>
    </item>
    
    <item>
      <title>RedDotRubyConf 2014 In Review</title>
      <description>&lt;p&gt;RedDotRubyConf is 4 years old now, and this is the 2nd year that I am running it.&lt;/p&gt;

&lt;p&gt;Although it&#39;s not my first, it&#39;s actually even tougher than the previous year,
because I really wanted to make sure that it would be bigger and better than before.&lt;/p&gt;

&lt;p&gt;Judging from the feedback so far, I think I did ok for the second time. :)&lt;/p&gt;

&lt;p&gt;At this moment, I am full of gratitude to everyone who helped made RDRC a success,
especially &lt;em&gt;Jaryl, Yink, Kevin, Alarice&lt;/em&gt; - my Ruby Heroes,
and &lt;a href=&quot;https://speakerdeck.com/winston/reddotrubyconf-2014-day-2?slide=17&quot;&gt;many others&lt;/a&gt;!&lt;/p&gt;

&lt;h2&gt;Thank You, Sponsors!&lt;/h2&gt;

&lt;p&gt;We have a lot more sponsors this year, and all of them are awesome!&lt;/p&gt;

&lt;p&gt;They didn&#39;t ask for much but just wanted to do their bit and help to build the community.
Hope the conference helped to boost their brand and even hire a few good folks too.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.neo.com&quot;&gt;Neo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.thoughtworks.com/&quot;&gt;ThoughtWorks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/&quot;&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.tinkerbox.com.sg/&quot;&gt;Tinkerbox&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.techinasia.com/&quot;&gt;TechInAsia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.engineyard.com/&quot;&gt;EngineYard&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://piktochart.com/&quot;&gt;Piktochart&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://odd-e.com/&quot;&gt;Odd-e&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.referralcandy.com/&quot;&gt;ReferralCandy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://modern.ie/en-us&quot;&gt;Microsoft&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.oreilly.com/&quot;&gt;O&#39;Reilly&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://pragprog.com/&quot;&gt;Pragmatic Bookshelf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://grabtaxi.com/singapore/&quot;&gt;GrabTaxi&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;Thank You, Speakers!&lt;/h2&gt;

&lt;p&gt;Speakers, we cannot do without any of you. All of you were awesome!&lt;/p&gt;

&lt;p&gt;28 speakers in all - 6 Key Notes, 14 CFPs and 6 Lightning Talks.&lt;/p&gt;

&lt;p&gt;I am sure all of us learned a ton from all the speakers in those 2 days.&lt;/p&gt;

&lt;p&gt;As I was running around most of the time, I didn&#39;t manage to listen to all the great talks.
Luckily, we have Confreaks covering the show this year, so I&#39;ll catch up on the talks soon.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/rdrc14-speakers.jpg&quot; alt=&quot;Speakers&quot; /&gt;&lt;/p&gt;

&lt;h2&gt;Thank YOU!&lt;/h2&gt;

&lt;p&gt;What is a conference without an audience? RedDotRubyConf is for all of you!&lt;/p&gt;

&lt;p&gt;Almost 350 Rubyists from all over the World gathered together for 2-days to celebrate Ruby on the tiny island called Singapore.&lt;/p&gt;

&lt;p&gt;This year, we also have the most number of female attendees and students,
and it&#39;s my hope to continue to grow the numbers for these two segments in the next year.&lt;/p&gt;

&lt;p&gt;Thank you all for your support!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/rdrc14-attendees.jpg&quot; alt=&quot;Speakers&quot; /&gt;&lt;/p&gt;

&lt;h2&gt;Infographics&lt;/h2&gt;

&lt;p&gt;Let&#39;s look at some infographics now, powered by &lt;a href=&quot;http://piktochart.com/&quot;&gt;Piktochart&lt;/a&gt;, one of our sponsors.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Piktochart is awesome! It&#39;s my first time using the service and I am blown away. Try it!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/rdrc14-infographics.jpg&quot; alt=&quot;Infographics&quot; /&gt;&lt;/p&gt;

&lt;h2&gt;Improvements&lt;/h2&gt;

&lt;p&gt;Of course, nothing is perfect, and the day after it ended,
I have already been thinking of improvements that I could do for 2015.&lt;/p&gt;

&lt;h3&gt;Ticketing and Registration&lt;/h3&gt;

&lt;p&gt;I really wanted to try out &lt;a href=&quot;http://about.peatix.com/colorsync.html?hl=en&quot;&gt;Peatix&#39;s Colorsync&lt;/a&gt;, but alas,
we have some restrictions that&#39;s better handled by the traditional spreadsheet method. Bummer..&lt;/p&gt;

&lt;p&gt;Anyway, next year, I hope to make the entire ticketing and registration experience better,
and also to find ways to make discovery and interactions amongst attendees easier.&lt;/p&gt;

&lt;h3&gt;Swag&lt;/h3&gt;

&lt;p&gt;I got some pretty bad lanyards, I know. Sorry! I&#39;ll fix it next year.&lt;/p&gt;

&lt;p&gt;Also, someone suggested actually giving out a book. Plausible. I&#39;ll consider that.&lt;/p&gt;

&lt;h3&gt;Breakfast and Water&lt;/h3&gt;

&lt;p&gt;Yes! There were breakfasts this year! I hope it helped to tide you till lunch time.&lt;/p&gt;

&lt;p&gt;But, I&#39;ll definitely up the quantity and variety next year.&lt;/p&gt;

&lt;p&gt;And it also seems like water is actually more popular than the sodas. Someone mentioned that maybe we are all more health conscious nowadays?&lt;/p&gt;

&lt;p&gt;Ok. Let&#39;s do more water and less sodas.&lt;/p&gt;

&lt;h3&gt;Cleanup&lt;/h3&gt;

&lt;p&gt;I received good feedback about the cocktail tables and how it encouraged conversations during lunch.&lt;/p&gt;

&lt;p&gt;However, at the same time, I am disappointed that a lot of the plates and soda cans were left on the cocktail tables after lunch. :(&lt;/p&gt;

&lt;p&gt;Also, with 350+ people, A LOT of trash is generated!&lt;/p&gt;

&lt;p&gt;Next year, I&#39;ll need to think about getting cleaning help.&lt;/p&gt;

&lt;h3&gt;Local Speakers&lt;/h3&gt;

&lt;p&gt;Same problem as last year. We need more local speakers! Where are all of you?&lt;/p&gt;

&lt;p&gt;How can I make more local speakers submit CFPs? Hmm..&lt;/p&gt;

&lt;h3&gt;Social Media&lt;/h3&gt;

&lt;p&gt;This year, I got the team contribute to &lt;a href=&quot;http://twitter.com/reddotrubyconf&quot;&gt;@reddotrubyconf&lt;/a&gt; during the conference.&lt;/p&gt;

&lt;p&gt;I think we can do more next year, with a &quot;social media plan&quot; to keep it entertaining for all.&lt;/p&gt;

&lt;h2&gt;Resources&lt;/h2&gt;

&lt;p&gt;I&#39;ll be updating these, but otherwise, &lt;a href=&quot;https://gist.github.com/cheeaun/abe650f6a0591f73014e&quot;&gt;Cheeaun&#39;s list&lt;/a&gt; is awesome too!&lt;/p&gt;

&lt;h3&gt;Slides&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;My Slides, &lt;a href=&quot;https://speakerdeck.com/winston/reddotrubyconf-2014-day-1&quot;&gt;Day 1&lt;/a&gt; and &lt;a href=&quot;https://speakerdeck.com/winston/reddotrubyconf-2014-day-2&quot;&gt;Day 2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Speakers&#39; slides are linked on &lt;a href=&quot;http://www.reddotrubyconf.com&quot;&gt;www.reddotrubyconf.com&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;Photos&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.flickr.com/photos/reddotrubyconf&quot;&gt;RedDotRubyConf&#39;s Flickr&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.flickr.com/photos/ngpestelos/sets/72157645418666805/&quot;&gt;Nestor Pestelos&#39;s Flickr&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://photos.faun.me/Events/RedDotRubyConf2014/&quot;&gt;Faun&#39;s Photos&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;Videos&lt;/h3&gt;

&lt;p&gt;Videos available on &lt;a href=&quot;http://confreaks.tv/events/rdrc2014&quot;&gt;Confreaks&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;Jobs Board&lt;/h3&gt;

&lt;p&gt;The full glory of our &lt;a href=&quot;https://www.flickr.com/photos/reddotrubyconf/14814698284/in/album-72157645731579799/&quot;&gt;Jobs Board&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;--&lt;/p&gt;

&lt;p&gt;That&#39;s it. See you all in 2015!&lt;/p&gt;

&lt;p&gt;Drop me an email - suggestions, compliments or criticisms. Thank you!&lt;/p&gt;
</description>
      <pubDate>Wed, 02 Jul 2014 00:00:00 +0800</pubDate>
      <link>http://winstonyw.com/2014/07/02/reddotrubyconf_2014_in_review/</link>
      <guid isPermaLink="true">http://winstonyw.com/2014/07/02/reddotrubyconf_2014_in_review/</guid>
    </item>
    
    <item>
      <title>Time.now vs Time.zone.now</title>
      <description>&lt;p&gt;Ruby &lt;code&gt;Time&lt;/code&gt; can get confusing when used in your Rails app. What &lt;code&gt;Time&lt;/code&gt; is it now?&lt;/p&gt;

&lt;p&gt;Suppose I have a server in UTC time and all of my users are from Singapore (GMT +08:00),
then your Rails app&#39;s &lt;code&gt;time_zone&lt;/code&gt; should be configured to SGT.&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;c1&quot;&gt;# config/application.rb&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# Run &amp;quot;rake -D time&amp;quot; for a list of tasks for finding time zone names. Default is UTC.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;time_zone&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Singapore&amp;#39;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Besides that, instead of using &lt;code&gt;Time.now&lt;/code&gt;, use &lt;code&gt;Time.zone.now&lt;/code&gt; especially when
you are printing time attributes as display to your users.&lt;/p&gt;

&lt;p&gt;Why? Let&#39;s explore the difference:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;irb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Time&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;zone&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Singapore&amp;quot;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Singapore&amp;quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;irb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Time&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;now&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2014&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mo&quot;&gt;03&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mo&quot;&gt;03&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mo&quot;&gt;07&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mo&quot;&gt;05&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mo&quot;&gt;0000&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;irb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Time&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;zone&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;now&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Mon&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;03&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Mar&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2014&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;19&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mo&quot;&gt;07&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;SGT&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;08&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;&lt;code&gt;Time.now&lt;/code&gt; uses the system time because it&#39;s is part of the Ruby standard library.&lt;/p&gt;

&lt;p&gt;However, &lt;code&gt;Time.zone.now&lt;/code&gt; returns the time, corrected to our Singapore time zone
because it&#39;s been &lt;a href=&quot;https://github.com/rails/rails/blob/master/activesupport/lib/active_support/core_ext/time/zones.rb#L11&quot;&gt;extended by ActiveSupport&lt;/a&gt; to have the &lt;code&gt;zone&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;Therefore, in order for your users to see the time in SGT, use &lt;code&gt;Time.zone.now&lt;/code&gt; in your code. In fact, use &lt;code&gt;Time.current&lt;/code&gt;. &lt;a href=&quot;https://github.com/rails/rails/blob/master/activesupport/lib/active_support/core_ext/time/calculations.rb#L29&quot;&gt;Read the code&lt;/a&gt; to find out what&#39;s the difference.&lt;/p&gt;

&lt;p&gt;What about &lt;code&gt;DateTime&lt;/code&gt;?&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;irb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Time&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;zone&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Singapore&amp;quot;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Singapore&amp;quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;irb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;DateTime&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;now&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Mon&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;03&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Mar&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2014&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;08&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mo&quot;&gt;0000&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;irb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;DateTime&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;in_time_zone&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Mon&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;03&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Mar&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2014&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;19&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;14&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;SGT&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;08&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;&lt;code&gt;DateTime&lt;/code&gt; returns the system time too because it&#39;s also part of the Ruby standard library.&lt;/p&gt;

&lt;p&gt;The method to convert &lt;code&gt;DateTime&lt;/code&gt; to our time zone is the &lt;code&gt;.in_time_zone&lt;/code&gt; method which &lt;a href=&quot;https://github.com/rails/rails/blob/master/activesupport/lib/active_support/core_ext/date_and_time/zones.rb#L19&quot;&gt;also accepts a time zone as a param&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now then.. What do you do when you query the database with ActiveRecord?&lt;/p&gt;

&lt;p&gt;You can use either &lt;code&gt;Time.now&lt;/code&gt; or &lt;code&gt;Time.current&lt;/code&gt;.
Both will work because ActiveRecord will convert the times to UTC before sending it to the database,
as all time columns in the database are also stored in UTC. Let&#39;s verify..&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;irb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Feedback&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;all&lt;/span&gt;
  &lt;span class=&quot;no&quot;&gt;Feedback&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Load&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ms&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;no&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;feedbacks&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;feedbacks&amp;quot;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;#&amp;lt;Feedback id: 1, created_at: &amp;quot;2014-03-03 11:29:26&amp;quot;, updated_at: &amp;quot;2014-03-03 11:29:26&amp;quot;&amp;gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Notice that &lt;code&gt;created_at&lt;/code&gt; and &lt;code&gt;updated_at&lt;/code&gt; columns are stored in UTC.&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;irb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Feedback&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;created_at&lt;/span&gt;
  &lt;span class=&quot;no&quot;&gt;Feedback&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Load&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ms&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;no&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;feedbacks&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;feedbacks&amp;quot;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ORDER&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;BY&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;feedbacks&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;id&amp;quot;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ASC&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;LIMIT&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Mon&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;03&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Mar&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2014&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;19&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;29&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;26&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;SGT&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;08&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;When you retrieve an object and print &lt;code&gt;created_at&lt;/code&gt;, it will be converted to your time zone.&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;irb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Time&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;now&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2014&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mo&quot;&gt;03&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mo&quot;&gt;03&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;41&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;31&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mo&quot;&gt;0000&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;irb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Feedback&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;where&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;created_at &amp;lt; ?&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Time&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;no&quot;&gt;Feedback&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Load&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ms&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;no&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;feedbacks&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;feedbacks&amp;quot;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;created_at&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;2014-03-03 11:41:32.687457&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;#&amp;lt;Feedback id: 1, created_at: &amp;quot;2014-03-03 11:29:26&amp;quot;, updated_at: &amp;quot;2014-03-03 11:29:26&amp;quot;&amp;gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;When you use &lt;code&gt;Time.now&lt;/code&gt;, it generates a SQL query with time in UTC.&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;irb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Time&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;current&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Mon&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;03&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Mar&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2014&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;19&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;22&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;SGT&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;08&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mo&quot;&gt;00&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;irb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Feedback&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;where&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;created_at &amp;lt; ?&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Time&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;current&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;no&quot;&gt;Feedback&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Load&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ms&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;no&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;feedbacks&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;feedbacks&amp;quot;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;created_at&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;2014-03-03 11:42:23.549020&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;#&amp;lt;Feedback id: 1, created_at: &amp;quot;2014-03-03 11:29:26&amp;quot;, updated_at: &amp;quot;2014-03-03 11:29:26&amp;quot;&amp;gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;When you use &lt;code&gt;Time.current&lt;/code&gt;, it also generates a SQL query with time in UTC.&lt;/p&gt;

&lt;p&gt;Hope this helps to explain &lt;code&gt;Time&lt;/code&gt; in Rails!&lt;/p&gt;

&lt;p&gt;Further reading:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.elabs.se/blog/36-working-with-time-zones-in-ruby-on-rails&quot;&gt;Working with time zones in Ruby on Rails&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://danilenko.org/2012/7/6/rails_timezones/&quot;&gt;The Exhaustive Guide to Rails Time Zones&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <pubDate>Mon, 03 Mar 2014 00:00:00 +0800</pubDate>
      <link>http://winstonyw.com/2014/03/03/time_now_vs_time_zone_now/</link>
      <guid isPermaLink="true">http://winstonyw.com/2014/03/03/time_now_vs_time_zone_now/</guid>
    </item>
    
    <item>
      <title>Spring And Failing Specs</title>
      <description>&lt;p&gt;&lt;a href=&quot;https://github.com/rails/spring&quot;&gt;Spring&lt;/a&gt; will be &lt;a href=&quot;http://edgeguides.rubyonrails.org/4_1_release_notes.html&quot;&gt;included in Rails 4.1&lt;/a&gt; as the defacto Application Preloader.
It&#39;s similar to &lt;a href=&quot;https://github.com/burke/zeus&quot;&gt;Zeus&lt;/a&gt; which keeps your application running in the background during development,
so that any rake or spec command will run speedily without having to reload the app.&lt;/p&gt;

&lt;p&gt;Anyway, I was using &lt;code&gt;spring&lt;/code&gt;, &lt;code&gt;spring-commands-rspec&lt;/code&gt; and &lt;code&gt;enumerize&lt;/code&gt; gems in my app
and was running specs with &lt;code&gt;spring rspec&lt;/code&gt; when this happened:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$&amp;gt; spring rspec

........F.............................

Failures:

  1) Feedback validations
     Failure/Error: it { should enumerize(:emotion).in(:happy, :sad) }
     NoMethodError:
       undefined method `enumerize&#39; for #&amp;lt;RSpec::Core::ExampleGroup::Nested_3::Nested_2:0x000001029bcd20&amp;gt;
     # ./spec/models/feedback_spec.rb:22:in `block (3 levels) in &amp;lt;top (required)&amp;gt;&#39;
     # -e:1:in `&amp;lt;main&amp;gt;&#39;

Finished in 0.27399 seconds
38 examples, 1 failure
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;However, if I just do &lt;code&gt;rspec&lt;/code&gt;, the specs passed!&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$&amp;gt; rspec

......................................

Finished in 0.27061 seconds
38 examples, 0 failures

Randomized with seed 2852
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Dug into the problem and found that this was a loading issue with &lt;code&gt;enumerize&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This was how the &lt;code&gt;enumerize&lt;/code&gt; matchers were loaded:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;defined?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;RSpec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;enumerize/integrations/rspec&amp;#39;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;And it works fine for plain &lt;code&gt;rspec&lt;/code&gt; command because &lt;code&gt;rspec&lt;/code&gt; loads before &lt;code&gt;rails&lt;/code&gt;.
However, when &lt;code&gt;spring&lt;/code&gt; starts the application, &lt;code&gt;rspec&lt;/code&gt; is not yet loaded and so
the matchers will not be required as well.&lt;/p&gt;

&lt;p&gt;The fix is to load &lt;code&gt;rspec&lt;/code&gt; like this:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;begin&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;rspec/matchers&amp;#39;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;rescue&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;LoadError&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;enumerize/integrations/rspec&amp;#39;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;This makes sure that the &lt;code&gt;enumerize&lt;/code&gt; matchers will only required when &lt;code&gt;rspec/matchers&lt;/code&gt; can be required without errors,
which means it will only load in dev or test environment because you shouldn&#39;t have &lt;code&gt;rspec&lt;/code&gt; bundled in your production environment.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/brainspec/enumerize/pull/143&quot;&gt;Pull request over here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Keep this in mind when you encounter weird failing specs when using &lt;code&gt;spring&lt;/code&gt;.&lt;/p&gt;
</description>
      <pubDate>Mon, 03 Mar 2014 00:00:00 +0800</pubDate>
      <link>http://winstonyw.com/2014/03/03/spring_and_failing_specs/</link>
      <guid isPermaLink="true">http://winstonyw.com/2014/03/03/spring_and_failing_specs/</guid>
    </item>
    
    <item>
      <title>Passion Drives You To Do Crazy Things</title>
      <description>&lt;p&gt;Many of you would know, I left Pivotal Labs/Neo Innovations in October to join a startup, and now, I&#39;ll be leaving the startup too.&lt;/p&gt;

&lt;p&gt;--&lt;/p&gt;

&lt;p&gt;Since the day I learned about Ruby, I know it&#39;s going to change my life.&lt;/p&gt;

&lt;p&gt;Since the day I learned about Agile practices, I know it&#39;s going to change many people&#39;s lives.&lt;/p&gt;

&lt;p&gt;I might have exaggerated a little, but right now these are the two things I am passionate about.&lt;/p&gt;

&lt;p&gt;I believe that the World (or Singapore for a start) can do with more Ruby engineers,
and companies can benefit from Agile practices such as Pair Programming, Test Driven Development, Continuous Integration, Retrospectives etc.&lt;/p&gt;

&lt;p&gt;Having worked with Friendster.com, Viki.com, many other startups and even Government agencies while I was with Pivotal Labs,
I am confident of the value that Ruby and/or Agile can bring to a company.&lt;/p&gt;

&lt;p&gt;With that in mind, I have decided to step out to pursue my ambition of helping companies in Singapore grow through the sharing of my knowledge in these areas.&lt;/p&gt;

&lt;p&gt;Being employed with a startup unfortunately doesn&#39;t afford me the convenience to help others or startups
and although I have been doing this in my spare time (e.g. Rails InstallFest), I realized that I really want to do this on a fulltime basis.&lt;/p&gt;

&lt;p&gt;It&#39;s crazy, but the calling is strong and this could be my version of self-actualization.&lt;/p&gt;

&lt;p&gt;--&lt;/p&gt;

&lt;p&gt;In the last year, I have met lots of people in the startup industry
when I was running monthy Ruby meetups and organizing RedDotRubyConf 2013.&lt;/p&gt;

&lt;p&gt;I realised that despite the availability of funding for these startups in Singapore,
a lot of them do not have access to a ready pool of engineering talents or knowledge of how to manage an engineering team effectively.&lt;/p&gt;

&lt;p&gt;This means that the startups have to first solve the problems of engineering shortage and engineering management
before they can tackle the problem that the startup was originally formed to solve.&lt;/p&gt;

&lt;p&gt;Hence I see an opportunity for me to try and help solve these problems with my experience in Ruby and in Agile practices.&lt;/p&gt;

&lt;p&gt;As an experiment, I worked with a friend, who runs a company doing Joomla, for two weeks and shared with him Ruby on Rails and Agile practices.&lt;/p&gt;

&lt;p&gt;We did pair programming and he&#39;s now a convert to Ruby on Rails, and exploring the possibility of using Ruby more for their projects.
The Agile practices have also helped improved the processes in his company, and in his words &quot;made my engineers very happy&quot;.&lt;/p&gt;

&lt;p&gt;To hear that really touched me and further reaffirmed my decision to step out.&lt;/p&gt;

&lt;p&gt;I have the ability to help make engineers happy and I should continue to do it!&lt;/p&gt;

&lt;p&gt;--&lt;/p&gt;

&lt;p&gt;So what am I going to do?&lt;/p&gt;

&lt;p&gt;I have several ideas right now on what I can do, but nothing concrete yet.
I&#39;ll be working for the startup until January to help ease the transition, though my notice period is just one week.
After that, I&#39;ll take some time off for a few weeks to distill my thoughts and to firm up my action plans.&lt;/p&gt;

&lt;p&gt;I could be doing Ruby on Rails courses, Agile consultation, Pair Programming etc.
But whichever it is, my guiding principle is clear - I want to share my knowledge and do more for the local startup community.&lt;/p&gt;

&lt;p&gt;Meanwhile, if you would just like to chat or you have advice for me, feel free to reach out!&lt;/p&gt;

&lt;p&gt;Anyway, fail also ok. At least I tried! It&#39;s going to be an exciting 2014 ahead.&lt;/p&gt;
</description>
      <pubDate>Sun, 22 Dec 2013 00:00:00 +0800</pubDate>
      <link>http://winstonyw.com/2013/12/22/passion_drives_you_to_do_crazy_things/</link>
      <guid isPermaLink="true">http://winstonyw.com/2013/12/22/passion_drives_you_to_do_crazy_things/</guid>
    </item>
    
    <item>
      <title>Singapore Rails InstallFest</title>
      <description>&lt;h2&gt;Background&lt;/h2&gt;

&lt;p&gt;For the last year, I have been toying with the idea of starting a basic Ruby on Rails class to help people get started with Ruby on Rails.&lt;/p&gt;

&lt;p&gt;I wanted to do it to grow the Ruby community in Singapore, and because teaching is FUN!
However, I didn&#39;t have time to work on the materials, and so I never got anything started.&lt;/p&gt;

&lt;p&gt;One day, I came across &lt;a href=&quot;https://groups.google.com/forum/#!topic/rails-oceania/8pXB_JP7SbY&quot;&gt;this thread on &quot;Ruby or Rails Oceania&quot;&lt;/a&gt;
about Rails InstallFest, and I was immediately excited as it seems to be aligned with what I had in mind.&lt;/p&gt;

&lt;p&gt;And so, I emailed &lt;a href=&quot;https://twitter.com/lindsaar&quot;&gt;Mikel&lt;/a&gt; of &lt;a href=&quot;http://www.reinteractive.net/&quot;&gt;reInteractive&lt;/a&gt; to enquire about the possibility and he referred me to Chloe, reInteractive&#39;s Community Manager
who was really enthusiastic about helping us get started with the Rails InstallFest.&lt;/p&gt;

&lt;h2&gt;The Event&lt;/h2&gt;

&lt;p&gt;Rails InstallFest happened on 5 Oct 2013, 9:30am at &lt;a href=&quot;http://siliconstraits.com/&quot;&gt;Silicon Straits CO.LAB&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;At first, I was really worried about the turnout as it poured heavily in the morning on 5 Oct.
But my fears were unfounded as we saw a total of 27 partcipants and 8 volunteer coaches.
The particpants came from all sorts of background including product/business folks, developers, designers and students.&lt;/p&gt;

&lt;p&gt;For our first Rails InstallFest, this is what the partipants have to do:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Get Ruby on Rails installed on your machine using the &lt;a href=&quot;http://railsinstaller.org&quot;&gt;Rails Installer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Follow this &lt;a href=&quot;http://blog.reinterative.net/posts/32&quot;&gt;blog post&lt;/a&gt; and get a blog deployed on Heroku&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;At the end of the day, all of the participants got Ruby on Rails installed on their laptops,
and about half of them got a simple blog deployed on Heroku. Yea!&lt;/p&gt;

&lt;h2&gt;Thank You&lt;/h2&gt;

&lt;p&gt;reInteractive really helped a lot in making the first Singapore Rails InstallFest a success.
Especially Chloe, who helped made sure I have all that I need - materials and vouchers!
Without them, the event wouldn&#39;t have happened. Thank you reInteractive and Chloe!&lt;/p&gt;

&lt;p&gt;We also required a venue for the event, and James readily offered his space for our use.
Silicon Straits was really &lt;em&gt;cosy&lt;/em&gt; and &lt;em&gt;conducive for learning&lt;/em&gt; as remarked by a number of the participants in their feedback,
and I am really grateful to James for loaning out his space! Thank you James and Silicon Straits!&lt;/p&gt;

&lt;p&gt;And finally, all I can say is that the Singapore Ruby community is sooooooo full of love!
After I annouced the event and asked for volunteer coaches, many stepped up!&lt;/p&gt;

&lt;p&gt;Thank you Chong-Yee, Jeffrey, Jaryl, Kevin, Paul, Ray Chuan and Sean
for volunteering your time on a Saturday morning as coaches!&lt;/p&gt;

&lt;h2&gt;Improvements&lt;/h2&gt;

&lt;p&gt;We collected feedback from the participants and the overall sentiment is that
the class was a really useful session to help them get started in Ruby on Rails.&lt;/p&gt;

&lt;p&gt;At the same time, most remarked that the volunteer coaches were friendly and helpful.
Together with the conducive environment, they found learning RoR to be easy.&lt;/p&gt;

&lt;p&gt;However, it would have been better if we did a brief walkthrough of the blog post exercise,
so that the participants can better appreciate and understand what they were doing,
and not just blindly follow the blog post.&lt;/p&gt;

&lt;p&gt;In addition, there&#39;s also a suggestion to group the participants into small learning teams so that they interact and learn from one another within their small groups.&lt;/p&gt;

&lt;p&gt;--&lt;/p&gt;

&lt;p&gt;Overall, I enjoyed running the first Rails InstallFest in SG,
and I am sure we&#39;ll continue to have more RoR training sessions in the future. =)&lt;/p&gt;

&lt;p&gt;Time for some pictures!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/rails_installfest-1.jpg&quot; alt=&quot;Silicon Straits&quot; /&gt;
&lt;img src=&quot;/assets/images/rails_installfest-2.jpg&quot; alt=&quot;Attendees&quot; /&gt;
&lt;img src=&quot;/assets/images/rails_installfest-3.jpg&quot; alt=&quot;Attendees&quot; /&gt;
&lt;img src=&quot;/assets/images/rails_installfest-4.jpg&quot; alt=&quot;Attendees&quot; /&gt;&lt;/p&gt;
</description>
      <pubDate>Mon, 07 Oct 2013 00:00:00 +0800</pubDate>
      <link>http://winstonyw.com/2013/10/07/rails_installfest/</link>
      <guid isPermaLink="true">http://winstonyw.com/2013/10/07/rails_installfest/</guid>
    </item>
    
    <item>
      <title>OpenURI's open, Tempfile and StringIO</title>
      <description>&lt;p&gt;&lt;code&gt;OpenURI#open&lt;/code&gt; has a dual personality. Consider the code below..&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;open-uri&amp;#39;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;zipfile&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;http://example.com/file.zip&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;With this, &lt;code&gt;zipfile&lt;/code&gt; can either be a &lt;code&gt;Tempfile&lt;/code&gt; instance or a &lt;code&gt;StringIO&lt;/code&gt; instance.&lt;/p&gt;

&lt;p&gt;Apparently, that&#39;s how &lt;code&gt;OpenURI#open&lt;/code&gt; works, and this &lt;a href=&quot;http://stackoverflow.com/questions/10496874/why-does-openuri-treat-files-under-10kb-in-size-as-stringio&quot;&gt;StackOverFlow post&lt;/a&gt; explains it well.
And as mentioned in the same post, to get &lt;code&gt;OpenURI#open&lt;/code&gt; to always return a &lt;code&gt;Tempfile&lt;/code&gt;,
apply the initializer &quot;hack&quot;.&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;open-uri&amp;#39;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Don&amp;#39;t allow downloaded files to be created as StringIO. Force a tempfile to be created.&lt;/span&gt;
&lt;span class=&quot;no&quot;&gt;OpenURI&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Buffer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;send&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:remove_const&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;StringMax&amp;#39;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;OpenURI&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Buffer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;const_defined?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;StringMax&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;no&quot;&gt;OpenURI&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Buffer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;const_set&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;StringMax&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Or, you can just be deterministic and &lt;a href=&quot;http://winstonyw.com/2013/10/01/ruby_reading_a_remote_zip_file/&quot;&gt;create the Tempfile yourself&lt;/a&gt;.&lt;/p&gt;
</description>
      <pubDate>Wed, 02 Oct 2013 00:00:00 +0800</pubDate>
      <link>http://winstonyw.com/2013/10/02/openuris_open_tempfile_and_stringio/</link>
      <guid isPermaLink="true">http://winstonyw.com/2013/10/02/openuris_open_tempfile_and_stringio/</guid>
    </item>
    
    <item>
      <title>Ruby - Reading A Remote Zip File</title>
      <description>&lt;p&gt;I need to access a remote zip file and this is something that works:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;c1&quot;&gt;# In the console, gem install &amp;quot;httparty&amp;quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;httparty&amp;quot;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# In the console, gem install &amp;quot;rubyzip&amp;quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;zip&amp;quot;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Get the contents of the remote zip file via HTTParty&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# and write it into a temp zip file&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;zipfile&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Tempfile&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;file&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;zipfile&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;binmode&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# This might not be necessary depending on the zip file&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;zipfile&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;HTTParty&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;http://localhost:3000/file.zip&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;zipfile&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;close&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Unzip the temp zip file and process the contents&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# Let garbage collection delete the temp zip file&lt;/span&gt;

&lt;span class=&quot;no&quot;&gt;Zip&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;zipfile&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# Do whatever you want with the contents&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The code is simple, but at the start, I kept getting an error when unzipping the temp zip file,
and I thought I was doing something wrong.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;End-of-central-directory signature not found
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Did some debugging and finally figured out that the problem was with the remote zip file
- because the file was not fully constructed even though I had a link to it.&lt;/p&gt;

&lt;p&gt;The remote zip file link was actually returned by an earlier API call to an external service
that also triggered the building of the remote zip file.&lt;/p&gt;

&lt;p&gt;Moral of the story? Trust my code.&lt;/p&gt;

&lt;p&gt;Anyway, &lt;a href=&quot;http://blog.huangzhimin.com/2012/10/02/avoid-using-rubyzip/&quot;&gt;RubyZip is poor in performance&lt;/a&gt;. Might want to try &lt;a href=&quot;http://zipruby.rubyforge.org/&quot;&gt;ZipRuby&lt;/a&gt; instead.&lt;/p&gt;
</description>
      <pubDate>Tue, 01 Oct 2013 00:00:00 +0800</pubDate>
      <link>http://winstonyw.com/2013/10/01/ruby_reading_a_remote_zip_file/</link>
      <guid isPermaLink="true">http://winstonyw.com/2013/10/01/ruby_reading_a_remote_zip_file/</guid>
    </item>
    
  </channel>
</rss>
