<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-924015769731377256</id><updated>2026-08-27T00:45:29.523-07:00</updated><category term="ios"/><category term="objective-c"/><category term="alcatraz"/><category term="alfred"/><category term="animated tabs"/><category term="apple"/><category term="bash"/><category term="beginning"/><category term="beginning ios development"/><category term="bettersnaptool"/><category term="blog"/><category term="books"/><category term="c++"/><category term="chrome"/><category term="chromium"/><category term="clang"/><category term="clangformat"/><category term="coding standards javascript ruby"/><category term="developer"/><category term="development"/><category term="evernote"/><category term="git github merge code interactive rebase"/><category term="google"/><category term="ios ios7 iphone status bar mobile"/><category term="llvm"/><category term="meetups"/><category term="mozilla"/><category term="oh-my-zsh"/><category term="podcast"/><category term="productive"/><category term="productivity tools"/><category term="resources"/><category term="ruby"/><category term="ruby 1.9.3-p125 rails rvm rbenv linux install source code bundler"/><category term="ruby metaprogramming class_eval rails"/><category term="ruby on rails"/><category term="ruby on rails 3 mysql2 windows 7 64bit"/><category term="ruby on rails 3.1 mongodb mongoid dynamic attributes"/><category term="ruby on rails 3.1 rspec paperclip mongoid"/><category term="ruby rogues"/><category term="swift"/><category term="timeout"/><category term="tutorial"/><category term="xcode"/><category term="zsh"/><title type='text'>Paul&#39;s Software Blog</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://paul-wong-jr.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/924015769731377256/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://paul-wong-jr.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>10</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-924015769731377256.post-8611760947732743674</id><published>2015-01-11T19:42:00.000-08:00</published><updated>2015-01-11T19:42:08.881-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="apple"/><category scheme="http://www.blogger.com/atom/ns#" term="beginning"/><category scheme="http://www.blogger.com/atom/ns#" term="beginning ios development"/><category scheme="http://www.blogger.com/atom/ns#" term="blog"/><category scheme="http://www.blogger.com/atom/ns#" term="books"/><category scheme="http://www.blogger.com/atom/ns#" term="ios"/><category scheme="http://www.blogger.com/atom/ns#" term="objective-c"/><category scheme="http://www.blogger.com/atom/ns#" term="resources"/><category scheme="http://www.blogger.com/atom/ns#" term="swift"/><category scheme="http://www.blogger.com/atom/ns#" term="tutorial"/><title type='text'>Resources for Beginning iOS Development</title><content type='html'>Recently, a coworker was interested in learning iOS development and asked me to recommend to him a few resources for learning and I thought that I would also share this here.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;Here are a couple resources for learning iOS:&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s2&quot;&gt;&lt;b&gt;Intro Books&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;1.&amp;nbsp;&lt;a href=&quot;http://www.amazon.com/iOS-Programming-Ranch-Guide-Guides/dp/0321942051/ref=sr_1_1?ie=UTF8&amp;amp;qid=1420953595&amp;amp;sr=8-1&amp;amp;keywords=ios+big+nerd+ranch&quot;&gt;&lt;span class=&quot;s3&quot;&gt;iOS Programming: The Big Nerd Ranch Guide (4th Edition)&lt;/span&gt;&lt;/a&gt;&amp;nbsp;- This book only covers iOS 7 and Objective-C, but a lot of the same concepts will apply in iOS 8. This would be good intro to iOS and also learning Objective-C. Some of the text might be out of date since the Xcode UI has changed a little bit. I originally started learning with the Beginning iPhone Development book (below), and I read this one after; I thought that the Big Nerd Ranch book went in to more in depth on almost all the topics and I was able to pick a few tips on how to better structure my code.&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;2.&amp;nbsp;&lt;a href=&quot;http://www.amazon.com/Beginning-iPhone-Development-Swift-Exploring/dp/1484204107&quot;&gt;Beginning iPhone Development with Swift: Exploring the iOS SDK&lt;/a&gt; - This book is also gives a good intro to iPhone development, but this one is written for iOS 8 and is in Swift if you want to skip the Objective-C part.&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s2&quot;&gt;&lt;b&gt;Learning Swift&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;1. I recommend just reading Apple&#39;s book on Swift to learn the language. It&#39;s available in iBooks&amp;nbsp;&lt;a href=&quot;https://itunes.apple.com/us/book/swift-programming-language/id881256329?mt=11&quot;&gt;&lt;span class=&quot;s3&quot;&gt;here&lt;/span&gt;&lt;/a&gt;&amp;nbsp;and on the web&amp;nbsp;&lt;a href=&quot;https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/&quot;&gt;&lt;span class=&quot;s3&quot;&gt;here&lt;/span&gt;&lt;/a&gt;.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;2. There is also a second part of the book above that covers using Swift with Cocoa and Objective-C, which goes into more advanced topics but is a good follow up read after reading the first part. The iBooks link is &lt;a href=&quot;https://itunes.apple.com/us/book/using-swift-cocoa-objective/id888894773?mt=11&quot;&gt;here&lt;/a&gt;.&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;s1&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span class=&quot;s1&quot;&gt;A common question I see is should I learn Swift or Objective-C? I think that if you are looking for a job as a iOS developer, you will need to learn both because most likely the company/client already has existing code that is in Objective-C. You can mix and match Swift and Objective-C code, but you need an understanding of both to do so. If you are able to develop an app from scratch, you can probably get away with only learning Swift. It is also good to point out that the 3rd party library support for Swift is very weak right now, so if you don&#39;t mind reinventing the wheel (a good way to learn) then this is the way to go. You can also always refer to open source libraries written in Objective-C and convert them to Swift yourself (another benefit for learning both languages).&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p2&quot;&gt;
&lt;span class=&quot;s1&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;p1&quot;&gt;
&lt;span class=&quot;s2&quot;&gt;&lt;b&gt;Other resources (tutorial sites and blogs)&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p3&quot;&gt;
&lt;span class=&quot;s4&quot;&gt;1.&amp;nbsp;&lt;span class=&quot;s3&quot;&gt;&lt;a href=&quot;http://www.raywenderlich.com/&quot;&gt;http://www.raywenderlich.com/&lt;/a&gt;&amp;nbsp;- This site has a lot of useful tutorials for not only beginners but also intermediate and advanced iOS developers. When I was first starting out, I frequented this site and tried to do as many tutorials as I could. Even still today, I find myself visiting this site to continue learning.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p3&quot;&gt;
&lt;span class=&quot;s4&quot;&gt;2.&amp;nbsp;&lt;span class=&quot;s3&quot;&gt;&lt;a href=&quot;http://nshipster.com/&quot;&gt;http://nshipster.com/&lt;/a&gt;&amp;nbsp;- This iOS blog is written by the creator of AFNetworking and has a lot of in depth articles on Cocoa, Objective-C and Swift topics that are commonly overlooked.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;p4&quot;&gt;
&lt;span class=&quot;s5&quot;&gt;3.&amp;nbsp;&lt;span class=&quot;s6&quot;&gt;&lt;a href=&quot;https://iosdevweekly.com/&quot;&gt;https://iosdevweekly.com/&lt;/a&gt;&amp;nbsp;- This newsletter is a great way to get a pulse on the iOS community. I&#39;ve been able to learn about a lot of useful tools and libraries from this weekly email.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;s5&quot;&gt;&lt;span class=&quot;s6&quot;&gt;4. &lt;a href=&quot;https://developer.apple.com/videos/wwdc/2014/&quot;&gt;WWDC videos&lt;/a&gt; (all years) - The videos from the WWDC presentations are extremely useful, but can be quite advanced and dry sometimes. If you are unsure of what the best practice of doing something is, I would recommended these videos; It&#39;s also a great way to learn about the new things that were introduced in every new version of iOS. Also see &lt;a href=&quot;http://asciiwwdc.com/&quot;&gt;ASCIIwwdc&lt;/a&gt;.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;s5&quot;&gt;&lt;span class=&quot;s6&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;s5&quot;&gt;&lt;span class=&quot;s6&quot;&gt;Hopefully this is a good enough start. There is also always the Apple docs (sometimes confusing and hard to find), Google and Stack Overflow. Good luck!&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://paul-wong-jr.blogspot.com/feeds/8611760947732743674/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://paul-wong-jr.blogspot.com/2015/01/resources-for-beginning-ios-development.html#comment-form' title='15 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/924015769731377256/posts/default/8611760947732743674'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/924015769731377256/posts/default/8611760947732743674'/><link rel='alternate' type='text/html' href='http://paul-wong-jr.blogspot.com/2015/01/resources-for-beginning-ios-development.html' title='Resources for Beginning iOS Development'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>15</thr:total></entry><entry><id>tag:blogger.com,1999:blog-924015769731377256.post-6770978719335330027</id><published>2014-12-30T11:02:00.001-08:00</published><updated>2014-12-30T11:09:26.430-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="alfred"/><category scheme="http://www.blogger.com/atom/ns#" term="animated tabs"/><category scheme="http://www.blogger.com/atom/ns#" term="bash"/><category scheme="http://www.blogger.com/atom/ns#" term="bettersnaptool"/><category scheme="http://www.blogger.com/atom/ns#" term="chrome"/><category scheme="http://www.blogger.com/atom/ns#" term="developer"/><category scheme="http://www.blogger.com/atom/ns#" term="development"/><category scheme="http://www.blogger.com/atom/ns#" term="evernote"/><category scheme="http://www.blogger.com/atom/ns#" term="ios"/><category scheme="http://www.blogger.com/atom/ns#" term="meetups"/><category scheme="http://www.blogger.com/atom/ns#" term="oh-my-zsh"/><category scheme="http://www.blogger.com/atom/ns#" term="podcast"/><category scheme="http://www.blogger.com/atom/ns#" term="productive"/><category scheme="http://www.blogger.com/atom/ns#" term="productivity tools"/><category scheme="http://www.blogger.com/atom/ns#" term="ruby"/><category scheme="http://www.blogger.com/atom/ns#" term="ruby on rails"/><category scheme="http://www.blogger.com/atom/ns#" term="ruby rogues"/><category scheme="http://www.blogger.com/atom/ns#" term="timeout"/><category scheme="http://www.blogger.com/atom/ns#" term="xcode"/><category scheme="http://www.blogger.com/atom/ns#" term="zsh"/><title type='text'>Productivity Tools</title><content type='html'>There are several tools that I use daily to help improve my productivity not only as a developer, but also as a regular computer user. I think it is important to share these types of tools, interesting tidbits, or libraries on a weekly basis because there are just so many new things being created all the time.&lt;br /&gt;
&lt;br /&gt;
For example, I went to a few Ruby on Rails &lt;a href=&quot;http://www.meetup.com/SFRails/&quot;&gt;meetups&lt;/a&gt; and the first item on the agenda was always &quot;Sharing of Tools and Tips&quot;; here people would share new Ruby gems they had discovered or even share their experiences in solving a recent problem. Another great example is the &lt;a href=&quot;http://devchat.tv/ruby-rogues/&quot;&gt;Ruby Rogues Podcast&lt;/a&gt;&amp;nbsp;where after every show, each speaker has picks that they share with the group; these picks aren&#39;t always technical, but it&#39;s a great way to be cognizant of what is out there. At my current job, we have tech talks every Thursday, but before we start, I reserve 10-15 minutes for sharing of tools and tips or just anything that people found interesting for the week. Usually atleast one thing of interest comes from it, and I think just that makes the entire exercise worth it.&lt;br /&gt;
&lt;br /&gt;
Here are my picks:&lt;br /&gt;
&lt;br /&gt;
1.&amp;nbsp;&lt;a href=&quot;https://itunes.apple.com/us/app/bettersnaptool/id417375580?mt=12&quot;&gt;BetterSnapTool&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh95CYWgRlnbFZLuU-EhnXi70U6YmfkBV-UlfbhXA19SYip5WeOtvPKqho742FXRHrkxMkiEz1IHYnUROaq1DXCcwTav7n9xx_XUhLddUhSPz-MTEz-YQsR6ax9KoyNdS89j9pPUKsWQvE/s1600/Screen+Shot+2014-12-30+at+9.44.13+AM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh95CYWgRlnbFZLuU-EhnXi70U6YmfkBV-UlfbhXA19SYip5WeOtvPKqho742FXRHrkxMkiEz1IHYnUROaq1DXCcwTav7n9xx_XUhLddUhSPz-MTEz-YQsR6ax9KoyNdS89j9pPUKsWQvE/s1600/Screen+Shot+2014-12-30+at+9.44.13+AM.png&quot; height=&quot;312&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
Ever need to compare two windows side by side, but find it a pain to resize and arrange them all the time? BetterSnapTool makes this simple, and can snap windows to any side you want with just a keyboard shortcut. You can also define custom hotspots where if you drag a window to it, it will resize that window to a custom size that you previously specified. This is a paid tool, but I know that there are probably similar tools that are free.&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;u style=&quot;color: #0000ee;&quot;&gt;&lt;br /&gt;&lt;/u&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
2.&amp;nbsp;&lt;u style=&quot;color: #0000ee;&quot;&gt;&lt;a href=&quot;http://www.alfredapp.com/&quot;&gt;Alfred&lt;/a&gt;&lt;/u&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
Alfred allows you to do a lot of things from your fingertips. With a keyboard shortcut, it launches a spotlight like prompt that lets you search for files, launch applications, and even do arithmetic. I have to admit, I have been using this a lot less lately because the new spotlight in Mac OS X Yosemite is quite good. But I use to use this to launch all my development apps after logging in. You can also launch gmail straight from the prompt. I haven&#39;t explored this yet, but there is a PowerPack that you can purchase that allows you to define custom workflows. For example, I could define a development workflow, and it would allow me to launch all of my developer applications with one keyboard shortcut.&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
3. &lt;a href=&quot;http://www.dejal.com/timeout/&quot;&gt;Timeout&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9uUQ5UJ-PwJ37t4wkK50pKk84oMW2yuloKOfYHHeiO42AqWEP1A8FSO8qF3ICuNdcVrMcTQLtddCcANXPXiNk2k0i9s9l6cHvwKGqibXcZrimYAZFrhAB8sRl6j5ZtnhYJjd9I_mdSS4/s1600/Screen+Shot+2014-12-30+at+10.56.31+AM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9uUQ5UJ-PwJ37t4wkK50pKk84oMW2yuloKOfYHHeiO42AqWEP1A8FSO8qF3ICuNdcVrMcTQLtddCcANXPXiNk2k0i9s9l6cHvwKGqibXcZrimYAZFrhAB8sRl6j5ZtnhYJjd9I_mdSS4/s1600/Screen+Shot+2014-12-30+at+10.56.31+AM.png&quot; height=&quot;408&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
I&#39;ve built a lot of bad habits when using computers since I was young; I use to sit at the computer for 8-12+ hours straight and not take breaks. This has caused me a lot of eye and hand problems as I grew older, and I learned that it is REALLY important to take regular breaks from the computer. This tool helps remind me to take 10 second breaks, every 20 minutes, and 10 minute breaks every 60 minutes. This is all customizable as well. An important exercise I learned from my optometrist is the 20/20 rule, which is every 20 minutes, take a 20 second break and look at something atleast 20 feet away.&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
3. &lt;a href=&quot;https://evernote.com/&quot;&gt;Evernote&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
A little more heavy weight than the default Notes app, but I like it because I can type up notes for a presentation on my laptop, and then access these same notes on my phone during the presentation. You can also categorize your notes in to notebooks, which has been useful because I create a lot of notes.&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
4. &lt;a href=&quot;http://en.wikipedia.org/wiki/Z_shell&quot;&gt;zsh&lt;/a&gt; and the &lt;a href=&quot;https://github.com/robbyrussell/oh-my-zsh&quot;&gt;oh-my-zsh&lt;/a&gt; plugin&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPiQnVXRjxXL-VmY2TsA9wQP4y80SMF_Fx7-QD0bZAcSFrfqIIUBUrhy0ubScDOciEcZ8y9rIp616OUd770gmq3_Dt9rbBPAkjqzzKXfpDYpBAU34ekyBr1-HHKjBZ4clE1JgwAI21gzM/s1600/Screen+Shot+2014-12-30+at+11.04.32+AM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPiQnVXRjxXL-VmY2TsA9wQP4y80SMF_Fx7-QD0bZAcSFrfqIIUBUrhy0ubScDOciEcZ8y9rIp616OUd770gmq3_Dt9rbBPAkjqzzKXfpDYpBAU34ekyBr1-HHKjBZ4clE1JgwAI21gzM/s1600/Screen+Shot+2014-12-30+at+11.04.32+AM.png&quot; height=&quot;472&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
I&#39;ve mostly just used bash shell since it is the default on Mac OS X, but I recently decided to try zsh because I&#39;ve heard a lot about it. There are a few nice features in zsh that bash doesn&#39;t have, but I wouldn&#39;t say anything ground breaking. To list a few:&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Inline glob expansion: For example, type rm *.pdf and then hit tab.&lt;/li&gt;
&lt;li&gt;Interactive path expansion: Type cd /u/l/b and hit tab.&lt;/li&gt;
&lt;li&gt;Customizable prompt configuration options.&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
What I enjoy the most is what the oh-my-zsh plugin offers. The plugin basically offers a nice way to manage your zsh configuration, but it comes a ton of built in plugins and themes. I mainly just use a theme and a git plugin (which can probably be done in bash too with aliases), but it is still definitely worth checking out. I am sure that I am only scratching the surface. Here is my &lt;a href=&quot;https://github.com/paulsfds/dotfiles/blob/master/.zshrc&quot;&gt;zsh config&lt;/a&gt; if you would like to take a look.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
5. &lt;a href=&quot;http://animatedtabs.com/&quot;&gt;Animated Tabs&lt;/a&gt; for Chrome&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDwDVhA10Rhnv0_W3cheKqlnIa_GSHZCOmetWOG7GBP3JFMZUu_GLbx3InBEhdQWxo_2nTF-MBz8NecZvQMEFkPwevTOlQWlnM5zsDI77C45sF4rfxBMZcf9vR1mLueuyHgykNUeAMO78/s1600/Screen+Shot+2014-12-30+at+10.53.43+AM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDwDVhA10Rhnv0_W3cheKqlnIa_GSHZCOmetWOG7GBP3JFMZUu_GLbx3InBEhdQWxo_2nTF-MBz8NecZvQMEFkPwevTOlQWlnM5zsDI77C45sF4rfxBMZcf9vR1mLueuyHgykNUeAMO78/s1600/Screen+Shot+2014-12-30+at+10.53.43+AM.png&quot; height=&quot;310&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Lastly, I wanted to show an anti-productivity tool that I use quite often in Chrome. Usually I&#39;ll want to search for something, so I&#39;ll open a new Chrome tab and then I&#39;ll see some funny animated gif and then forget what I was doing and even what I was searching for. Although this interrupts my productivity during the day, sometimes it is nice to take a little break and laugh :).&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Here are a few other tools that have been recommended to me by colleagues, but I just haven&#39;t had a chance to check them out yet:&lt;/div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://fluidapp.com/&quot;&gt;Fluid App&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://itunes.apple.com/us/app/caffeine/id411246225?mt=12&quot;&gt;Caffeine&lt;/a&gt;&amp;nbsp;- Prevent computer from going in to screensaver or turning the display off on battery.&amp;nbsp;This is useful for Skype calls or meetings where you&#39;re watching someone else&#39;s screen but not interacting with your computer.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://kapeli.com/dash&quot;&gt;Dash&lt;/a&gt; -&amp;nbsp;For local copies of documentation for various platforms and libraries. Its nice having a local and searchable copy.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://lastpass.com/&quot;&gt;LastPass&lt;/a&gt; - For account management&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://itunes.apple.com/us/app/pauses/id481375590?mt=12&quot;&gt;Pauses&lt;/a&gt; - An alternative to Timeout&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://itunes.apple.com/us/app/flycut-clipboard-manager/id442160987?mt=12&quot;&gt;Flycut&lt;/a&gt; - Clipboard manager&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://filedart.com/&quot;&gt;Filedart&lt;/a&gt; - Speedy file sharing&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://paul-wong-jr.blogspot.com/feeds/6770978719335330027/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://paul-wong-jr.blogspot.com/2014/12/productivity-tools.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/924015769731377256/posts/default/6770978719335330027'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/924015769731377256/posts/default/6770978719335330027'/><link rel='alternate' type='text/html' href='http://paul-wong-jr.blogspot.com/2014/12/productivity-tools.html' title='Productivity Tools'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh95CYWgRlnbFZLuU-EhnXi70U6YmfkBV-UlfbhXA19SYip5WeOtvPKqho742FXRHrkxMkiEz1IHYnUROaq1DXCcwTav7n9xx_XUhLddUhSPz-MTEz-YQsR6ax9KoyNdS89j9pPUKsWQvE/s72-c/Screen+Shot+2014-12-30+at+9.44.13+AM.png" height="72" width="72"/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-924015769731377256.post-7715071520295216028</id><published>2014-11-15T14:23:00.000-08:00</published><updated>2014-11-15T14:23:41.540-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="git github merge code interactive rebase"/><title type='text'>Git Merge Workflow on Github</title><content type='html'>&lt;h1&gt;
How to Merge Code&lt;/h1&gt;
Below is a guide that I wrote for a recent project explaining a git merge workflow on Github. Often times, when you develop a new feature, you will create a new branch off of master called a feature branch. On the feature branch, you might have many commits to save your progress, or when you complete certain milestones of that feature. Once you finish the feature, you will want to merge this branch back to the master branch. However, you might not want all your commits to show up in the git log history because they were only for development purposes. We can overcome this issue by using a feature of git called interactive rebasing which allows you to squash certain commits and customize the commits that will eventually show up once the branch is merged to master. I have described the steps to achieve this outcome below.
&lt;br /&gt;
&lt;h2&gt;
Table of Contents&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.blogger.com/blogger.g?blogID=924015769731377256#purpose&quot;&gt;Purpose&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.blogger.com/blogger.g?blogID=924015769731377256#detailed-steps&quot;&gt;Detailed Steps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.blogger.com/blogger.g?blogID=924015769731377256#additional-reading&quot;&gt;Additional Reading&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h2&gt;
&lt;a href=&quot;https://www.blogger.com/blogger.g?blogID=924015769731377256#purpose&quot; name=&quot;purpose&quot;&gt;&lt;/a&gt;Purpose&lt;/h2&gt;
This guide explains how to develop and commit your code using git and GitHub. A developer should create a feature branch when developing new code. In the feature branch, a developer may commit multiple times during development including making changes based on comments from a code review. When development is completed and the feature branch is ready to be merged in to the master branch, the developer should squash the commits in to one, so that the git log history is kept clean.&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;
&lt;a href=&quot;https://www.blogger.com/blogger.g?blogID=924015769731377256#detailed-steps&quot; name=&quot;detailed-steps&quot;&gt;&lt;/a&gt;Detailed Steps&lt;/h2&gt;
1. On the `master` branch, `git pull` to make sure your code is up to date.&lt;br /&gt;
&lt;br /&gt;
2. Create a feature branch `git checkout -b name-of-feature-branch`. Note, you will automatically be switched to this new feature branch you are creating.&lt;br /&gt;
&lt;br /&gt;
3. Write code and develop your feature.&lt;br /&gt;
&lt;br /&gt;
4. `git commit` your code. Note, this step may be performed as many times as you prefer during development in order to maintain a history of your code changes.&lt;br /&gt;
&lt;br /&gt;
5. Once development is completed (and all your code is committed), we should make sure that our code is up to date with the latest `master` branch. On your feature branch, `git rebase master` will ensure that your branch is up to date and your code is compatible with the latest `master`. Also this step ensures that your commits are at the top, which is critical for the next steps.
Note that, during the rebase, you may encounter merge conflicts that will need to be resolved.&lt;br /&gt;
&lt;br /&gt;
6. Now we need to push our code to GitHub. `git push origin name-of-feature-branch` (while on the name-of-feature-branch branch) to push the branch to GitHub.&lt;br /&gt;
&lt;br /&gt;
7. In GitHub, create a pull request for the name-of-feature-branch branch and assign someone to review your code.&lt;br /&gt;
&lt;br /&gt;
8. If the reviewer makes comments or suggestions, please address them by asking for clarification and/or committing the changes. The reviewer also needs to give approval on whether or not the code is ready to be merged.&lt;br /&gt;
&lt;br /&gt;
9. Once the code is ready to be merged, it is time to squash your commits. Note, this doesn&#39;t apply if you only have one commit to merge, and in that case you can just merge your pull request on GitHub. First we need to know at what point your branch and master diverge. This is required as you only want to squash your commits.&lt;br /&gt;
&lt;br /&gt;
10. To do this run `git merge-base master `. This command should spit out a commit hash such as _918310dca623fac2d46198324814695c4726017e_. You will then use this hash to tell git &quot;_squash the commits from this point on_&quot;.&lt;br /&gt;
&lt;br /&gt;
11. Once you have your merge base commit run `git rebase -i `, for example: `git rebase -i 918310dca623fac2d46198324814695c4726017e`.&lt;br /&gt;
&lt;br /&gt;
12. Your text editor should popup and you should see your commits with the word `pick` in front of them. For all commits except the first one, change `pick` to `squash` or `s`, which will squash all of these commits in to one. Now save and quit your text editor.&lt;br /&gt;
&lt;br /&gt;
13. Another text editor window should pop up now, and here you can enter the commit message you would like to show up. This commit contains all of your commits squashed together.&lt;br /&gt;
&lt;br /&gt;
14. In order for this to work with your existing GitHub pull request (because we are rewriting the git log history), we need to `git push origin name-of-feature-branch -f`, which forces the push to overwrite the git log history in that pull request.&lt;br /&gt;
&lt;br /&gt;
15. You should see that on your GitHub pull request, the history should only contain the one commit that you squashed.&lt;br /&gt;
&lt;br /&gt;
16. Press the Merge button, and don&#39;t forget to delete your remote feature branch!
&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;
&lt;a href=&quot;https://www.blogger.com/blogger.g?blogID=924015769731377256#additional-reading&quot; name=&quot;additional-reading&quot;&gt;&lt;/a&gt;Additional Reading&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://help.github.com/articles/about-git-rebase&quot;&gt;https://help.github.com/articles/about-git-rebase&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://help.github.com/articles/using-git-rebase&quot;&gt;https://help.github.com/articles/using-git-rebase&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://git-scm.com/book/en/Git-Tools-Rewriting-History&quot;&gt;http://git-scm.com/book/en/Git-Tools-Rewriting-History&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://gitready.com/advanced/2009/02/10/squashing-commits-with-rebase.html&quot;&gt;http://gitready.com/advanced/2009/02/10/squashing-commits-with-rebase.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content><link rel='replies' type='application/atom+xml' href='http://paul-wong-jr.blogspot.com/feeds/7715071520295216028/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://paul-wong-jr.blogspot.com/2014/11/git-merge-workflow-on-github.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/924015769731377256/posts/default/7715071520295216028'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/924015769731377256/posts/default/7715071520295216028'/><link rel='alternate' type='text/html' href='http://paul-wong-jr.blogspot.com/2014/11/git-merge-workflow-on-github.html' title='Git Merge Workflow on Github'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-924015769731377256.post-4727504771814256852</id><published>2014-08-19T08:45:00.003-07:00</published><updated>2014-11-15T14:24:21.572-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="alcatraz"/><category scheme="http://www.blogger.com/atom/ns#" term="c++"/><category scheme="http://www.blogger.com/atom/ns#" term="chromium"/><category scheme="http://www.blogger.com/atom/ns#" term="clang"/><category scheme="http://www.blogger.com/atom/ns#" term="clangformat"/><category scheme="http://www.blogger.com/atom/ns#" term="coding standards javascript ruby"/><category scheme="http://www.blogger.com/atom/ns#" term="google"/><category scheme="http://www.blogger.com/atom/ns#" term="ios"/><category scheme="http://www.blogger.com/atom/ns#" term="llvm"/><category scheme="http://www.blogger.com/atom/ns#" term="mozilla"/><category scheme="http://www.blogger.com/atom/ns#" term="objective-c"/><title type='text'>Coding Styles and Standards</title><content type='html'>&lt;div style=&quot;color: #333333; font-family: &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 15px; line-height: 24.375px; margin-bottom: 1.625em;&quot;&gt;
One of the main reasons for having coding standards is to keep your code readable by everyone. By enforcing standards and formatting, the code base becomes consistent, and anyone can easily understand the structure of the code because he will be more familiar with what to expect. It is also very useful when a new developer joins the team because once he is familiar with the patterns, he will be able to easily read the existing code, which results in a more pleasant experience.&lt;/div&gt;
&lt;div style=&quot;color: #333333; font-family: &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 15px; line-height: 24.375px; margin-bottom: 1.625em;&quot;&gt;
In this example, I will define coding standards for an iOS project (which uses Objective-C). We will take advantage of the fact that code formatting can be automated in XCode by using a plugin. The coding style that I chose is based on the&amp;nbsp;&lt;a data-mce-href=&quot;http://www.chromium.org/developers/coding-style&quot; href=&quot;http://www.chromium.org/developers/coding-style&quot; style=&quot;color: #1b8be0; font-style: inherit; font-weight: inherit; line-height: 1.625; text-decoration: none;&quot;&gt;Chromium&lt;/a&gt;&amp;nbsp;style guide, but I made a few modifications, which can be found in the `.clang-format` file. Feel free to make changes as you see fit; All of the options are defined here&amp;nbsp;&lt;a data-mce-href=&quot;http://clang.llvm.org/docs/ClangFormatStyleOptions.html&quot; href=&quot;http://clang.llvm.org/docs/ClangFormatStyleOptions.html&quot; style=&quot;color: #1b8be0; font-style: inherit; font-weight: inherit; line-height: 1.625; text-decoration: none;&quot;&gt;LLVM Coding Standards&lt;/a&gt;.&lt;/div&gt;
&lt;div style=&quot;color: #333333; font-family: &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 15px; line-height: 24.375px; margin-bottom: 1.625em;&quot;&gt;
&lt;strong style=&quot;color: inherit; font-style: inherit; line-height: 1.625;&quot;&gt;Installation&lt;/strong&gt;&lt;br /&gt;
1. Install&amp;nbsp;&lt;a data-mce-href=&quot;https://github.com/supermarin/Alcatraz&quot; href=&quot;https://github.com/supermarin/Alcatraz&quot; style=&quot;color: #1b8be0; font-style: inherit; font-weight: inherit; line-height: 1.625; text-decoration: none;&quot;&gt;Alcatraz&lt;/a&gt;, the package manager for XCode.&lt;br /&gt;
&lt;code style=&quot;color: inherit; font-family: Monaco, Consolas, &#39;Andale Mono&#39;, &#39;DejaVu Sans Mono&#39;, monospace; font-size: 13px; line-height: normal;&quot;&gt;`curl -fsSL https://raw.github.com/supermarin/Alcatraz/master/Scripts/install.sh | sh`&lt;/code&gt;&lt;br /&gt;
2. Select `Package Manager` from the `Window` menu and search for `ClangFormat` and install that plugin.&lt;br /&gt;
3. Select `Clang Format` from the `Edit` menu, and click on `File`. This will load formatting settings from the `.clang-format` file that is located in the repository.&lt;br /&gt;
4. When you want to format a file, go to the `Clang Format` menu and select `Format File in Focus`. You can also enable `Enable Format on Save` to have the plugin automatically format the file when you save it. You can also bind formatting to a keyboard shortcut, refer to the&amp;nbsp;&lt;a data-mce-href=&quot;https://github.com/travisjeffery/ClangFormat-Xcode&quot; href=&quot;https://github.com/travisjeffery/ClangFormat-Xcode&quot; style=&quot;color: #1b8be0; font-style: inherit; font-weight: inherit; line-height: 1.625; text-decoration: none;&quot;&gt;ClangFormat homepage&lt;/a&gt;&amp;nbsp;for more options.&lt;/div&gt;
&lt;h2 style=&quot;clear: both; font-family: &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 15px; line-height: 24.375px; margin: 0px 0px 0.8125em;&quot;&gt;
&lt;a class=&quot;mce-item-anchor&quot; href=&quot;https://www.blogger.com/null&quot; name=&quot;additional-standards&quot; style=&quot;-webkit-user-modify: read-only; -webkit-user-select: all; background: url(http://blog.grio.com/wp-includes/js/tinymce/skins/lightgray/img/anchor.gif) 50% 50% no-repeat rgb(213, 213, 213); border: 1px dotted rgb(58, 58, 58); color: #1b8be0; cursor: default; display: inline-block; font-style: inherit; font-weight: inherit; height: 9px !important; line-height: 1.625; width: 9px !important;&quot;&gt;&lt;/a&gt;Additional Standards&lt;/h2&gt;
&lt;div style=&quot;color: #333333; font-family: &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 15px; line-height: 24.375px; margin-bottom: 1.625em;&quot;&gt;
The automatic code formatter does not implement all the standards we would like to follow. There are some standards that need to be enforced by the developer himself because they can&#39;t be automated. Please refer to&amp;nbsp;&lt;a data-mce-href=&quot;https://github.com/paulsfds/objective-c-style-guide&quot; href=&quot;https://github.com/paulsfds/objective-c-style-guide&quot; style=&quot;color: #1b8be0; font-style: inherit; font-weight: inherit; line-height: 1.625; text-decoration: none;&quot;&gt;https://github.com/paulsfds/objective-c-style-guide&lt;/a&gt;&amp;nbsp;to see some examples.&lt;/div&gt;
&lt;h2 style=&quot;clear: both; font-family: &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 15px; line-height: 24.375px; margin: 0px 0px 0.8125em;&quot;&gt;
&lt;a class=&quot;mce-item-anchor&quot; href=&quot;https://www.blogger.com/null&quot; name=&quot;other-languages&quot; style=&quot;-webkit-user-modify: read-only; -webkit-user-select: all; background: url(http://blog.grio.com/wp-includes/js/tinymce/skins/lightgray/img/anchor.gif) 50% 50% no-repeat rgb(213, 213, 213); border: 1px dotted rgb(58, 58, 58); color: #1b8be0; cursor: default; display: inline-block; font-style: inherit; font-weight: inherit; height: 9px !important; line-height: 1.625; width: 9px !important;&quot;&gt;&lt;/a&gt;Other Languages&lt;/h2&gt;
&lt;div style=&quot;color: #333333; font-family: &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 15px; line-height: 24.375px; margin-bottom: 1.625em;&quot;&gt;
Coding standards are universal and there exists some popular ones for other languages. I would also suggest searching on Google for popular standards for your favorite language. Also, many well established companies such as&amp;nbsp;&lt;a data-mce-href=&quot;https://code.google.com/p/google-styleguide/&quot; href=&quot;https://code.google.com/p/google-styleguide/&quot; style=&quot;color: #1b8be0; font-style: inherit; font-weight: inherit; line-height: 1.625; text-decoration: none;&quot;&gt;Google have their own coding standards&lt;/a&gt;&amp;nbsp;that are available to the public. Here are a few popular ones to take a look at:&lt;/div&gt;
&lt;div style=&quot;color: #333333; font-family: &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 15px; line-height: 24.375px; margin-bottom: 1.625em;&quot;&gt;
&lt;strong style=&quot;color: inherit; font-style: inherit; line-height: 1.625;&quot;&gt;JavaScript&lt;/strong&gt;&lt;/div&gt;
&lt;ul style=&quot;color: #333333; font-family: &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 15px; line-height: 24.375px; list-style: square; margin: 0px 0px 1.625em 2.5em; padding: 0px;&quot;&gt;
&lt;li style=&quot;color: inherit; font-style: inherit; font-weight: inherit; line-height: 1.625;&quot;&gt;&lt;a data-mce-href=&quot;https://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml&quot; href=&quot;https://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml&quot; style=&quot;color: #1b8be0; font-style: inherit; font-weight: inherit; line-height: 1.625; text-decoration: none;&quot;&gt;Google JavaScript Style Guide&lt;/a&gt;&lt;/li&gt;
&lt;li style=&quot;color: inherit; font-style: inherit; font-weight: inherit; line-height: 1.625;&quot;&gt;&lt;a data-mce-href=&quot;http://www.jshint.com/&quot; href=&quot;http://www.jshint.com/&quot; style=&quot;color: #1b8be0; font-style: inherit; font-weight: inherit; line-height: 1.625; text-decoration: none;&quot;&gt;JSHint&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div style=&quot;color: #333333; font-family: &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 15px; line-height: 24.375px; margin-bottom: 1.625em;&quot;&gt;
&lt;strong style=&quot;color: inherit; font-style: inherit; line-height: 1.625;&quot;&gt;Ruby&lt;/strong&gt;&lt;/div&gt;
&lt;ul style=&quot;color: #333333; font-family: &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 15px; line-height: 24.375px; list-style: square; margin: 0px 0px 1.625em 2.5em; padding: 0px;&quot;&gt;
&lt;li style=&quot;color: inherit; font-style: inherit; font-weight: inherit; line-height: 1.625;&quot;&gt;&lt;a data-mce-href=&quot;https://github.com/bbatsov/ruby-style-guide&quot; href=&quot;https://github.com/bbatsov/ruby-style-guide&quot; style=&quot;color: #1b8be0; font-style: inherit; font-weight: inherit; line-height: 1.625; text-decoration: none;&quot;&gt;Ruby Style Guide&lt;/a&gt;&lt;/li&gt;
&lt;li style=&quot;color: inherit; font-style: inherit; font-weight: inherit; line-height: 1.625;&quot;&gt;&lt;a data-mce-href=&quot;https://github.com/thoughtbot/guides/tree/master/style&quot; href=&quot;https://github.com/thoughtbot/guides/tree/master/style&quot; style=&quot;color: #1b8be0; font-style: inherit; font-weight: inherit; line-height: 1.625; text-decoration: none;&quot;&gt;thoughtbot&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div style=&quot;color: #333333; font-family: &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 15px; line-height: 24.375px; margin-bottom: 1.625em;&quot;&gt;
&lt;strong style=&quot;color: inherit; font-style: inherit; line-height: 1.625;&quot;&gt;Objective-C&lt;/strong&gt;&lt;/div&gt;
&lt;ul style=&quot;color: #333333; font-family: &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 15px; line-height: 24.375px; list-style: square; margin: 0px 0px 1.625em 2.5em; padding: 0px;&quot;&gt;
&lt;li style=&quot;color: inherit; font-style: inherit; font-weight: inherit; line-height: 1.625;&quot;&gt;&lt;a data-mce-href=&quot;http://google-styleguide.googlecode.com/svn/trunk/objcguide.xml&quot; href=&quot;http://google-styleguide.googlecode.com/svn/trunk/objcguide.xml&quot; style=&quot;color: #1b8be0; font-style: inherit; font-weight: inherit; line-height: 1.625; text-decoration: none;&quot;&gt;Google Objective-C Style Guide&lt;/a&gt;&lt;/li&gt;
&lt;li style=&quot;color: inherit; font-style: inherit; font-weight: inherit; line-height: 1.625;&quot;&gt;&lt;a data-mce-href=&quot;https://github.com/NYTimes/objective-c-style-guide&quot; href=&quot;https://github.com/NYTimes/objective-c-style-guide&quot; style=&quot;color: #1b8be0; font-style: inherit; font-weight: inherit; line-height: 1.625; text-decoration: none;&quot;&gt;New York Times&lt;/a&gt;&lt;/li&gt;
&lt;li style=&quot;color: inherit; font-style: inherit; font-weight: inherit; line-height: 1.625;&quot;&gt;&lt;a data-mce-href=&quot;https://github.com/raywenderlich/objective-c-style-guide&quot; href=&quot;https://github.com/raywenderlich/objective-c-style-guide&quot; style=&quot;color: #1b8be0; font-style: inherit; font-weight: inherit; line-height: 1.625; text-decoration: none;&quot;&gt;raywenderlich.com&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div style=&quot;color: #333333; font-family: &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 15px; line-height: 24.375px; margin-bottom: 1.625em;&quot;&gt;
&lt;strong style=&quot;color: inherit; font-style: inherit; line-height: 1.625;&quot;&gt;C++&lt;/strong&gt;&lt;/div&gt;
&lt;ul style=&quot;color: #333333; font-family: &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 15px; line-height: 24.375px; list-style: square; margin: 0px 0px 1.625em 2.5em; padding: 0px;&quot;&gt;
&lt;li style=&quot;color: inherit; font-style: inherit; font-weight: inherit; line-height: 1.625;&quot;&gt;&lt;a data-mce-href=&quot;http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml&quot; href=&quot;http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml&quot; style=&quot;color: #1b8be0; font-style: inherit; font-weight: inherit; line-height: 1.625; text-decoration: none;&quot;&gt;Google C++ Style Guide&lt;/a&gt;&lt;/li&gt;
&lt;li style=&quot;color: inherit; font-style: inherit; font-weight: inherit; line-height: 1.625;&quot;&gt;&lt;a data-mce-href=&quot;http://www.chromium.org/developers/coding-style&quot; href=&quot;http://www.chromium.org/developers/coding-style&quot; style=&quot;color: #1b8be0; font-style: inherit; font-weight: inherit; line-height: 1.625; text-decoration: none;&quot;&gt;Chromium&lt;/a&gt;&lt;/li&gt;
&lt;li style=&quot;color: inherit; font-style: inherit; font-weight: inherit; line-height: 1.625;&quot;&gt;&lt;a data-mce-href=&quot;https://developer.mozilla.org/en-US/docs/Developer_Guide/Coding_Style&quot; href=&quot;https://developer.mozilla.org/en-US/docs/Developer_Guide/Coding_Style&quot; style=&quot;color: #1b8be0; font-style: inherit; font-weight: inherit; line-height: 1.625; text-decoration: none;&quot;&gt;Mozilla&lt;/a&gt;&lt;/li&gt;
&lt;li style=&quot;color: inherit; font-style: inherit; font-weight: inherit; line-height: 1.625;&quot;&gt;&lt;a data-mce-href=&quot;http://llvm.org/docs/CodingStandards.html&quot; href=&quot;http://llvm.org/docs/CodingStandards.html&quot; style=&quot;color: #1b8be0; font-style: inherit; font-weight: inherit; line-height: 1.625; text-decoration: none;&quot;&gt;LLVM&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div style=&quot;color: #333333; font-family: &#39;Helvetica Neue&#39;, Helvetica, Arial, sans-serif; font-size: 15px; line-height: 24.375px; margin-bottom: 1.625em;&quot;&gt;
What are your favorite coding styles and standards?&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://paul-wong-jr.blogspot.com/feeds/4727504771814256852/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://paul-wong-jr.blogspot.com/2014/08/coding-styles-and-standards.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/924015769731377256/posts/default/4727504771814256852'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/924015769731377256/posts/default/4727504771814256852'/><link rel='alternate' type='text/html' href='http://paul-wong-jr.blogspot.com/2014/08/coding-styles-and-standards.html' title='Coding Styles and Standards'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-924015769731377256.post-62196923716017329</id><published>2014-02-03T20:38:00.002-08:00</published><updated>2014-02-03T20:39:38.222-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ios ios7 iphone status bar mobile"/><title type='text'>Upgrading Your iPhone App to iOS 7: The New Status Bar</title><content type='html'>Hi everyone,&lt;br /&gt;
&lt;br /&gt;
It&#39;s been a while since I last blogged. I&#39;ve been neglecting my blog posting duties, but I hope to start posting more here this year. I&#39;ve picked up iOS development in the meanwhile, so I&#39;ll be posting some posts on that topic in addition to the usual Ruby on Rails ones.&lt;br /&gt;
&lt;br /&gt;
I&#39;ll start with this post that I wrote for work: &lt;a href=&quot;http://blog.grio.com/2013/10/upgrading-your-iphone-app-to-ios-7-the-new-status-bar.html&quot;&gt;http://blog.grio.com/2013/10/upgrading-your-iphone-app-to-ios-7-the-new-status-bar.html&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://paul-wong-jr.blogspot.com/feeds/62196923716017329/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://paul-wong-jr.blogspot.com/2014/02/upgrading-your-iphone-app-to-ios-7-new.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/924015769731377256/posts/default/62196923716017329'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/924015769731377256/posts/default/62196923716017329'/><link rel='alternate' type='text/html' href='http://paul-wong-jr.blogspot.com/2014/02/upgrading-your-iphone-app-to-ios-7-new.html' title='Upgrading Your iPhone App to iOS 7: The New Status Bar'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-924015769731377256.post-2245988294709810153</id><published>2012-04-19T20:00:00.000-07:00</published><updated>2012-04-19T20:00:10.117-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ruby metaprogramming class_eval rails"/><title type='text'>Ruby Metaprogramming with class_eval</title><content type='html'>One of the really cool and exciting aspects of using a dynamic programming language like Ruby is that you can generate code dynamically at runtime. Yup, you heard me, at runtime. Try doing something like this in Java. This is one of the features that allows all the magic that happens behind the scenes in Ruby on Rails possible. For example, this is how Rails&#39; attr_accessor automatically creates getters and setters for you. If you don&#39;t remember, you can call attr_accessor in an ActiveRecord class to define a &quot;virtual&quot; attribute, or in other words an attribute that isn&#39;t persisted in the database table. I want to explain this idea in more detail by creating a new method called attr_accessor_with_history, which is similar to attr_accessor, but it will also store the attribute&#39;s history. Say we have the following class: &lt;br /&gt;
&lt;pre class=&quot;rails&quot; name=&quot;code&quot;&gt;class Test
   attr_accessor_with_history :sample
end
&lt;/pre&gt;
Then this is how the attr_accessor_with_history method should work in the Ruby console: &lt;br /&gt;
&lt;pre class=&quot;rails&quot; name=&quot;code&quot;&gt;t = Test.new
t.sample = &quot;test&quot;  # =&amp;gt; &quot;test&quot;
t.sample = 1       # =&amp;gt; 1
t.sample = :abc    # =&amp;gt; :abc
t.sample_history   # =&amp;gt; [nil, &quot;test&quot;, 1, :abc]
&lt;/pre&gt;
So how can we do this? Let&#39;s first create a new file called class.rb and put the following inside: &lt;br /&gt;
&lt;pre class=&quot;rails&quot; name=&quot;code&quot;&gt;class Class
   def attr_accessor_with_history(attr_name)

   end
end
&lt;/pre&gt;
By defining our method in the class Class, all Ruby classes will be able to use it. This is because in Ruby, all classes are an object of the class Class. You can find more information in the API &lt;a href=&quot;http://www.ruby-doc.org/core-1.9.3/Class.html&quot;&gt;here&lt;/a&gt;. The second thing we want to know is that Ruby provides a method called class_eval, which takes a string and evaluates it in the context of the current class. So in our example, the class Test is calling our method, so when class_eval is called, it will be evaluated as if it were called in the class Test.
&lt;br /&gt;
&lt;br /&gt;
Let&#39;s take care of the easy part first, which is creating the attribute&#39;s getter methods. This is pretty straight forward because we don&#39;t really need to do anything special here.&lt;br /&gt;
&lt;pre class=&quot;rails&quot; name=&quot;code&quot;&gt;class Class
   def attr_accessor_with_history(attr_name)
      attr_name = attr_name.to_s         # make sure it&#39;s a string
      attr_reader attr_name              # create the attribute&#39;s getter
      attr_reader attr_name + &quot;_history&quot; # create bar_history getter

      # write our setter code below
      class_eval %Q(
                  def #{attr_name}=(attr_name)
                  end
                 )
   end
end
&lt;/pre&gt;
The %Q is Ruby syntax for an interpolated string, which allows us to create a string, and it will also interpret Ruby values such as anything in #{}. So in thinking about how to define our setter, we need to store the previous history of the variable. How can we do this? Well we can store stuff in an Array. If we push things in to the Array like a Stack, we can also figure out the order in which things were inserted. The one thing we need to be careful about is the initial case where we should initialize the array, and also insert the first value as nil. This is what we get:

&lt;br /&gt;
&lt;pre class=&quot;rails&quot; name=&quot;code&quot;&gt;class Class
   def attr_accessor_with_history(attr_name)
      attr_name = attr_name.to_s         # make sure it&#39;s a string
      attr_reader attr_name              # create the attribute&#39;s getter
      attr_reader attr_name + &quot;_history&quot; # create bar_history getter

      # write our setter code below
      class_eval %Q(
                  def #{attr_name}=(attr_name)
                     @#{attr_name} = attr_name

                     unless @#{attr_name + &quot;_history&quot;}
                        @#{attr_name + &quot;_history&quot;} = []
                        @#{attr_name + &quot;_history&quot;} &amp;lt;&amp;lt; nil
                     end

                     @#{attr_name + &quot;_history&quot;} &amp;lt;&amp;lt; attr_name

                   end
                 )
   end
end
&lt;/pre&gt;
First we set the value of the variable. Second, we check if the _history array has been initialized yet, and if it hasn&#39;t, then go ahead and initialize it. Lastly, we insert the new value into the _history array.
&lt;br /&gt;
&lt;br /&gt;
That was just a quick example of some of the cool things you can do with metaprogramming in Ruby. I want to end by showing a real world example of how I used metaprogramming on a project I&#39;m currently working on. If you haven&#39;t read my previous blog posts, I&#39;m working on a Rails site using MongoDB (with the Mongoid gem) that deals with computer games. I have a class called Event, and I need to define some scopes based on the game type so that I can do queries such as Event.all.starcraft2, which would return all Events that have a game attribute of &#39;starcraft2&#39;. I could easily hard code these scopes, but it will be annoying to always have to add a new scope every time we add support for a new game. Instead I can dynamically create these scopes using Ruby metaprogramming. &lt;br /&gt;
&lt;pre class=&quot;rails&quot; name=&quot;code&quot;&gt;  class_eval %Q(
              #{Constants::GAMES}.each_pair do |key, value|
                scope key, where(game: value)
              end
             )
&lt;/pre&gt;
First I need to explain the Constants::GAMES variable. I created a dynamic_fields.yml file that stores all the games that my application supports. Please refer to my previous post &lt;a href=&quot;http://paul-wong-jr.blogspot.com/2012/03/dynamic-attributes-and-mongodbmongoid.html&quot;&gt;here&lt;/a&gt; for more detailed information. So when my application loads, it reads in that YML file into the Constants::GAMES variable, which is a hash. The key is the game name as a symbol, and the value is the game name as a string. For each game, it will create a scope with the same name (as the game), and it does all of this automatically. I could have wrote a line of code for each game, but this is much cleaner to write and easier to maintain in the future.</content><link rel='replies' type='application/atom+xml' href='http://paul-wong-jr.blogspot.com/feeds/2245988294709810153/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://paul-wong-jr.blogspot.com/2012/04/ruby-metaprogramming-with-classeval.html#comment-form' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/924015769731377256/posts/default/2245988294709810153'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/924015769731377256/posts/default/2245988294709810153'/><link rel='alternate' type='text/html' href='http://paul-wong-jr.blogspot.com/2012/04/ruby-metaprogramming-with-classeval.html' title='Ruby Metaprogramming with class_eval'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-924015769731377256.post-196109664326567517</id><published>2012-04-06T15:22:00.000-07:00</published><updated>2012-04-09T13:43:36.165-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ruby 1.9.3-p125 rails rvm rbenv linux install source code bundler"/><title type='text'>Installing and compiling Ruby from the source code</title><content type='html'>There are several different ways to install Ruby with the most popular being &lt;a href=&quot;http://beginrescueend.com/&quot;&gt;RVM&lt;/a&gt;and &lt;a href=&quot;https://github.com/sstephenson/rbenv&quot;&gt;rbenv&lt;/a&gt;. Both have their advantages and disadvantages, but rbenv is a newer and more &quot;lightweight&quot; Ruby installer. I&#39;ll let you Google the differences between RVM and rbenv if you are more curious. I decided to install Ruby by downloading the source code and then compiling it myself. I&#39;ll be installing &lt;a href=&quot;http://www.ruby-lang.org/en/downloads/&quot;&gt;Ruby 1.9.3-p125&lt;/a&gt; (the latest version as of writing this) on Debian Linux 6 (Squeeze). 
&lt;br /&gt;
&lt;br /&gt;
1. First we need to install some development tools and libraries that Ruby needs to compile. Run the following commands from your terminal:
&lt;br /&gt;
&lt;pre class=&quot;rails&quot; name=&quot;code&quot;&gt;   apt-get install build-essential vim git-core curl

   apt-get install bison openssl libreadline6 libreadline6-dev zlib1g zlib1g-dev libssl-dev libyaml-dev libxml2-dev libxslt-dev autoconf libc6-dev ncurses-dev

   apt-get install libcurl4-openssl-dev libopenssl-ruby apache2-prefork-dev libapr1-dev libaprutil1-dev

   apt-get install libx11-dev libffi-dev tcl-dev tk-dev
&lt;/pre&gt;
Note you may need to run these commands as root or use sudo.
&lt;br /&gt;
&lt;br /&gt;
2. Download the latest version of Ruby here: &lt;a href=&quot;http://www.ruby-lang.org/en/downloads/&quot;&gt;http://www.ruby-lang.org/en/downloads/&lt;/a&gt; under the Compiling Ruby — Source code section.
&lt;br /&gt;
&lt;br /&gt;
3.  Extract the tar.gz file e.g. ruby-1.9.3-p125.tar.gz by typing: &lt;br /&gt;
&lt;pre class=&quot;rails&quot; name=&quot;code&quot;&gt;tar -xvf ruby-1.9.3-p125.tar.gz&lt;/pre&gt;
4. Open the README and follow the instructions on how to compile and install Ruby.
&lt;br /&gt;
&lt;pre class=&quot;rails&quot; name=&quot;code&quot;&gt;./configure
make
make test
make install
&lt;/pre&gt;
The install process will probably take a while, but once it&#39;s done, we can test to see if ruby installed successfully by typing &quot;ruby -v&quot; in the terminal. You should see something like, &quot;ruby 1.9.3p125 (2012-02-16 revision 34643) [i686-linux]&quot; if ruby installed correctly. Next we can install the Bundler and Rails gems to make sure Ruby is working correctly.

&lt;pre class=&quot;rails&quot; name=&quot;code&quot;&gt;
gem install bundler
gem install rails
&lt;/pre&gt;

Lastly, create a new Rails project to test to make sure everything works!</content><link rel='replies' type='application/atom+xml' href='http://paul-wong-jr.blogspot.com/feeds/196109664326567517/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://paul-wong-jr.blogspot.com/2012/04/installing-and-compiling-ruby-from.html#comment-form' title='26 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/924015769731377256/posts/default/196109664326567517'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/924015769731377256/posts/default/196109664326567517'/><link rel='alternate' type='text/html' href='http://paul-wong-jr.blogspot.com/2012/04/installing-and-compiling-ruby-from.html' title='Installing and compiling Ruby from the source code'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>26</thr:total></entry><entry><id>tag:blogger.com,1999:blog-924015769731377256.post-6521874076872457449</id><published>2012-03-07T00:39:00.000-08:00</published><updated>2012-03-07T00:39:07.914-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ruby on rails 3.1 mongodb mongoid dynamic attributes"/><title type='text'>Dynamic attributes and MongoDB/Mongoid</title><content type='html'>I recently started learning more about &lt;a href=&quot;http://www.mongodb.org/&quot;&gt;MongoDB&lt;/a&gt;, and how to use it in Rails 3.1 with the &lt;a href=&quot;http://mongoid.org/&quot;&gt;Mongoid&lt;/a&gt; gem. MongoDB is not your typical relational database; It is considered a NoSQL database because it stores your data in one huge JSON document instead of a bunch of relational tables. Actually, instead of storing the data in JSON, it stores it in BSON (Binary JSON) for performance reasons. The really cool thing about MongoDB is that it is schema-less, which allows you to store non-homogeneous objects in your database.&lt;br /&gt;
&lt;br /&gt;
Why is this cool you might ask? Well let me explain my problem; I want to create a web service that allows CRUD operations on objects called Events. Events have a name, start_time, and most importantly a game. Depending on the game attribute, each Event will have different game specific attributes. For example, I have an Event with a game value of &#39;starcraft2&#39;. Only Starcraft 2 Events have a region and a league attribute, while League of Legends Events have a min_elo attribute. How can we store these Event objects that have different attributes in our one document? We could do this in a standard MySQL database, but our table would be very wide, meaning we would have to have a column for every game specific attribute. This isn&#39;t very ideal because for each row, there would be a bunch of columns that wouldn&#39;t be used depending on the game.&lt;br /&gt;
&lt;br /&gt;
The great thing about Mongoid is that it supports dynamic attributes. I quote this from their &lt;a href=&quot;http://mongoid.org/docs/documents/dynamic.html&quot;&gt;website&lt;/a&gt;, &quot;By default Mongoid supports dynamic fields - that is it will allow attributes to get set and persisted on the document even if a field was not defined for them.&quot; This sounds like exactly what we need. We can just define the common Event attributes in the model itself, and then specify the game specific attributes at run time. So how do we go about doing this? Well, let&#39;s start with the Event model:&lt;br /&gt;
&lt;pre class=&quot;rails&quot; name=&quot;code&quot;&gt;class Event
   include Mongoid::Document

   field :name, type: String
   field :start_time, type: DateTime
   field :game, type: String
end
&lt;/pre&gt;This is pretty straight forward. Now the way I chose to define game specific attributes is by defining them in a YML file. I created a file called dynamic_fields.yml and put it in the Rails.root/config folder. Here is how I defined it:&lt;br /&gt;
&lt;pre class=&quot;rails&quot; name=&quot;code&quot;&gt;starcraft2:
   attributes:
      regions:
         name: regions
      leagues:
         name: leagues&lt;/pre&gt;You can define your dynamic attributes however you want, but this is just how I decided to do mine. So now that we have our Event model, and our Starcraft 2 attributes, how do we set these when an Event gets created, and how do we make sure these attributes only get set if the game is Starcraft 2? First we need to understand what mass assignment is, and how it could be a security vulnerability. &lt;a href=&quot;http://railscasts.com/episodes/26-hackers-love-mass-assignment&quot;&gt;Here&lt;/a&gt; is an excellent RailsCasts on that topic, but the gist of it is that when the server receives a POST request to create a new Event, it will take the parameters it receives and mass assign themto the matching attributes of the Event model. For example, if we had a User model, and a is_admin attribute, the user shouldn&#39;t be able to set the value of the is_admin attribute. If they could, then everyone could make themselves an admin when they create a new account. So how do we prevent this? In Rails there is a very useful method called attr_accessible that we can set on attributes in our model. Only the attributes you set using attr_accessible will be available for mass assignment. So let&#39;s do that for our Event model for all the common fields:&lt;br /&gt;
&lt;pre class=&quot;rails&quot; name=&quot;code&quot;&gt;class Event
   include Mongoid::Document

   field :name, type: String
   field :start_time, type: DateTime
   field :game, type: String

   attr_accessible :name, :start_time, :game
end
&lt;/pre&gt;This reason this is so important, especially in Mongoid is that since we enabled dynamic attributes, a user can create an Event with any additional attributes they want. They can add an attribute called &quot;some_random_field&quot; by including it in the POST parameters and it would be inserted in our database no questions asked. By setting attr_accessible on name, start_time, and game we are saying users can only set the values for these attributes and that&#39;s it. But there&#39;s a problem now, how do we set the values for our game specific attributes?&lt;br /&gt;
&lt;br /&gt;
Good thing for us, we can dynamically set attr_accessible thanks to this great RailsCast &lt;a href=&quot;http://railscasts.com/episodes/237-dynamic-attr-accessible&quot;&gt;here&lt;/a&gt;. I&#39;d recommend just watching the RailsCast to learn how to do this, but I want to mention that there are a couple changes that need to be made. The RailsCasts was filmed using Rails 3, but now that Rails 3.1 is out, we need to make some minor changes.&lt;br /&gt;
&lt;pre class=&quot;rails&quot; name=&quot;code&quot;&gt;class Event
   include Mongoid::Document

   field :name, type: String
   field :start_time, type: DateTime
   field :game, type: String

   attr_accessible :name, :start_time, :game

  # :accessible is a variable used to store the game specific dynamic fields so that they can be set through mass assignment via attr_accessible. this allows the attr_accessible to be set dynamically.
  attr_accessor :accessible

  private
  # Overrided so that extra variables can be added to the attr_accessible dynamically to allow mass assignment.
  def mass_assignment_authorizer(role = :default)
    super + (accessible || [])
  end
end
&lt;/pre&gt;We can now use the accessible variable in the EventsController to dynamically allow mass assignment of game specific attributes. The accessible variable is actually an array, and anything we put in that array will be added to attr_accessible since we overrided the mass_assignment_authorizer method.&lt;br /&gt;
&lt;br /&gt;
One last detour before we get to the final step. We first need to figure out how load the YML file that contains our dynamic attributes in to memory so that we know what attributes to add to attr_accessible. I want to load the dynamic attributes in to a global variable so that we can use it during the lifetime of the server. To do this, we can create a file called event_config.rb in our Rails.root/config/initializers folder. Whenever the rails server starts up, it will automatically load all the files in the initializers folder. We can load the YML in to memory by calling YAML.load() and passing it a file.&lt;br /&gt;
&lt;pre class=&quot;rails&quot; name=&quot;code&quot;&gt;module EventConfig
  DYNAMIC_FIELDS = YAML.load(File.open(&quot;#{Rails.root}/config/dynamic_fields.yml&quot;))
end
&lt;/pre&gt;Great, now we can access the DYNAMIC_FIELDS variable anywhere in our code. We have all the tools we need, so let&#39;s just jump right in to it. The DYNAMIC_FIELDS is a hash of what is defined in the YML file. So we can iterate through it by accessing the &#39;starcraft2&#39; key, and then that will return another hash. Inside the &#39;starcraft2&#39; hash we can acess the &#39;attributes&#39; key, which will give us another hash that contains the attributes we want. Then we can just iterate through the attributes hash&#39;s keys to get the attributes we want to set to be mass assignable.&lt;br /&gt;
&lt;pre class=&quot;rails&quot; name=&quot;code&quot;&gt;def create
   # we don&#39;t want to pass in the params right away because 
   # we have to set the accessible variable first
   @event = Event.new

   # the keys of the attribute hash are the game specific attributes 
   # we want to be assignable, so set the accessible variable to them
   game = params[:event][:game]
   @event.accessible = EventConfig::DYNAMIC_FIELDS[game][&#39;attributes&#39;].keys

   # lastly, set all the other attributes for the event using the params
   @event.attributes = params[:event]

   respond_to do |format|
      if @event.save
        format.html { redirect_to @event, notice: &#39;Event was successfully created.&#39; }
      else
        format.html { render action: &quot;new&quot; }
      end
    end
end
&lt;/pre&gt;That&#39;s it! It should work now, but how can we test this really easily? We can test it by using a tool called &lt;a href=&quot;http://curl.haxx.se/&quot;&gt;curl&lt;/a&gt;, which allows you to generate and send HTTP requests from the console. The most common use case will be a user filling out a form to create an Event on our server. Curl has a -F parameter, which we can use to emulate a filled-in form and it will send a HTTP POST request to the server. &lt;br /&gt;
&lt;pre class=&quot;rails&quot; name=&quot;code&quot;&gt;curl -F &#39;event[name]=curlTest&#39; -F &#39;event[game]=starcraft2&#39; -F &#39;event[regions]=North America&#39; -F &#39;event[leagues]=Grandmaster&#39; &#39;http://localhost:3000/events&#39;
&lt;/pre&gt;This should successfully create a new Event object in our database! We can also test to make sure that our attr_accessible is working correctly by not letting users set attributes that they shouldn&#39;t be setting. For example, we can try this:&lt;br /&gt;
&lt;pre class=&quot;rails&quot; name=&quot;code&quot;&gt;curl -F &#39;event[name]=curlTest&#39; -F &#39;event[game]=starcraft2&#39; -F &#39;event[regions]=North America&#39; -F &#39;event[leagues]=Grandmaster&#39; -F &#39;event[some_random_field]=should not get assigned&#39; &#39;http://localhost:3000/events&#39;
&lt;/pre&gt;In the rails server log, you should see this error message, &quot;WARNING: Can&#39;t mass-assign protected attributes: some_random_field.&quot; And we can see that it did create the Event, but without the some_random_field attribute.&lt;br /&gt;
&lt;br /&gt;
That&#39;s it, you are all set and ready to go! I hope that this post was helpful in understanding how dynamic attributes can be a cool and useful feature for your projects. Good luck, and until next time.</content><link rel='replies' type='application/atom+xml' href='http://paul-wong-jr.blogspot.com/feeds/6521874076872457449/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://paul-wong-jr.blogspot.com/2012/03/dynamic-attributes-and-mongodbmongoid.html#comment-form' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/924015769731377256/posts/default/6521874076872457449'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/924015769731377256/posts/default/6521874076872457449'/><link rel='alternate' type='text/html' href='http://paul-wong-jr.blogspot.com/2012/03/dynamic-attributes-and-mongodbmongoid.html' title='Dynamic attributes and MongoDB/Mongoid'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-924015769731377256.post-7354711462508444315</id><published>2012-02-15T16:51:00.041-08:00</published><updated>2012-03-06T00:45:09.480-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ruby on rails 3.1 rspec paperclip mongoid"/><title type='text'>Rails 3.1 testing with RSpec, Paperclip, and Mongoid</title><content type='html'>&lt;div&gt;Coming in to this, I did not know much about how RSpec testing worked. I watched a couple of &lt;a href=&quot;http://www.railscasts.com/&quot;&gt;RailsCasts &lt;/a&gt;(&lt;a href=&quot;http://railscasts.com/episodes/71-testing-controllers-with-rspec&quot;&gt;here&lt;/a&gt; and &lt;a href=&quot;http://railscasts.com/episodes/275-how-i-test&quot;&gt;here&lt;/a&gt;) to obtain a quick primer on the subject, but I still felt like it was not enough. So I decided to write this blog post in hopes that it will help anyone else who has had the same troubles as me. After watching the RailsCasts, the first thing I did was set up my test environment by installing the RSpec, FactoryGirl, and Guard gems. I will be writing tests for a model called Event and here is the basic structure of it:&lt;pre name=&quot;code&quot; class=&quot;rails&quot;&gt;class Event
   include Mongoid::Document
   include Mongoid::Paperclip

   field :name, type: String
   has_mongoid_attached_file :banner_image,
                 :storage =&amp;gt; :s3,               
                 :s3_credentials =&amp;gt; &quot;#{Rails.root}/config/amazon_s3.yml&quot;,                
                 :s3_permissions =&amp;gt;&#39;public-read&#39;,                
                 :s3_protocol =&amp;gt; &#39;http&#39;,               
                 :s3_headers =&amp;gt; {&#39;Expires&#39; =&amp;gt; 1.year.from_now.httpdate},                 
                 :url =&amp;gt; &#39;:s3_alias_url&#39;

   validates_presence_of :name, allow_nil: false
   validates_length_of :name, minimum: 1, maximum: 50, allow_blank: false
   validates_presence_of :start_time, allow_nil: false
end
&lt;/pre&gt;So if you installed RSpec before creating this Event model, it should invoke an RSpec generator to automatically create the file Rails.root/spec/models/event_spec.rb, but if you installed RSpec after the fact, then just create the file manually.&lt;br /&gt;
&lt;pre name=&quot;code&quot; class=&quot;rails&quot;&gt;require &#39;spec_helper&#39;

describe Event do

end
&lt;/pre&gt;So what are the most basic kinds of things that we can test in the model to start off? The easiest things I have found to test first are the model validations. The RSpec syntax is meant to be very human readable as you will see. The first validation to test is the mandatory presence of the name field. First we want to create a mock Event object to test with; we can do that by using FactoryGirl. To set up FactoryGirl, create a factories.rb file in the Rails.root/spec folder. This is where we will define what mock Event objects will look like, like so:&lt;pre name=&quot;code&quot; class=&quot;rails&quot;&gt;FactoryGirl.define do
   factory :event do
      name &#39;TestEvent&#39;
      start_time { Time.now }
   end
end
&lt;/pre&gt;Basically all our mock objects will have the name &#39;TestEvent&#39; and a start_time of right now. There are many more advanced options and features in FactoryGirl that are available (&lt;a href=&quot;https://github.com/thoughtbot/factory_girl/blob/master/GETTING_STARTED.md&quot;&gt;here&lt;/a&gt;), but for now let&#39;s keep things simple.&lt;br /&gt;
&lt;br /&gt;
Now back in the event_spec.rb file, I&#39;ll create a test called &quot;should require a name&quot;, which will test that our validates_presence_of :name is working correctly. First, we need to use FactoryGirl to create a mock Event object. We can do this by calling FactoryGirl.build(:event). Notice that I am using the build method (creates an object, but does not save it to the database), rather than the create method (creates an object, and does save it to the database). We actually want to test that an Event object without a name should not be valid. So to create a mock Event with no name, we can actually set the Event&#39;s name by passing it in like so: FactoryGirl.build(:event, :name =&amp;gt; nil). Putting this all together we get: &lt;pre name=&quot;code&quot; class=&quot;rails&quot;&gt;describe Event do
   it &quot;should require a name&quot; do
      event = FactoryGirl.build(:event, :name =&amp;gt; nil)
      event.should_not be_valid
   end
end
&lt;/pre&gt;The rest of the validation tests are similar and straight forward. I want to move on to the controller RSpec tests next. If this file is not already created, you should create it here Rails.root/spec/controllers/events_controller_spec.rb. Initially I had a lot of trouble trying to figure out how to write tests for the controller, but I came across a book called &lt;a href=&quot;http://pragprog.com/book/nrtest/rails-test-prescriptions&quot;&gt;Rails Test Prescriptions: Keeping Your Application Healthy&lt;/a&gt; that was quite helpful. Now I didn&#39;t buy or read this book, but I downloaded the free sample code from the book &lt;a href=&quot;http://pragprog.com/titles/nrtest/source_code&quot;&gt;here&lt;/a&gt;, and it contains some great examples of how to write simple tests for your basic CRUD controller methods. If you&#39;re interested in looking at the code, it is located in huddle3_rspec2/spec/controllers/projects_controller_spec.rb.&lt;br /&gt;
&lt;br /&gt;
Let&#39;s start with a simple test of making a GET request on the index method of the EventsController. Just like in the model tests, we want to create some mock Event objects by calling FactoryGirl.create_list(:event, 10), which will create 10 mock Event objects. Now when we perform a get :index in the test, it&#39;s going to run the code that we have in the controller. Looking at the index method, we can see that in order to get all the events, it calls @events = Event.all, which is great for regular use, but not so much for testing. During testing, we would like to have a controlled environment where we can control the data being returned. We can accomplish this by something called method stubbing. Method stubbing allows you to intercept method calls within a function (so the method in question will not actually be called), and allow you to return whatever data you want. Luckily, this is very easy to do in RSpec. Here is the code: &lt;pre name=&quot;code&quot; class=&quot;rails&quot;&gt;describe EventsController do
   describe &quot;GET index&quot; do
      it &quot;should assign all events as @events&quot; do
         events = FactoryGirl.create_list(:event, 10)
         Event.stub(:all).and_return(events)

         get :index

         assigns(:events).should eq(events)
      end
   end
end&lt;/pre&gt;Let&#39;s walk through this code. First we create 10 events that we are going to make the Event.all method return. Then we actually stub the :all method so that it returns the events we created. Now in order to invoke the controller code, we need to send a GET request to the index method, which is what get :index does. Finally, we need to check to make sure that the @events variable (in the index method in the controller) gets correctly set to what we expect it to be, which are the Events we created with FactoryGirl. The assigns() method in RSpec allows you to access the instance variables (variables with an @ in front of it) of the controller. This test should pass because we stub out the :all method and therefore the @events variable gets set to the 10 events that we created in the beginning.&lt;br /&gt;
&lt;br /&gt;
Now that we&#39;ve had a crash course in RSpec, we can write a test to test if file attachments are working correctly with Paperclip. Before we start, I need to mention that Paperclip comes with &lt;a href=&quot;http://rubydoc.info/gems/paperclip/Paperclip/Shoulda/Matchers&quot;&gt;RSpec matchers&lt;/a&gt;, which allow you test Paperclip specific attributes such as should have_attached_file(:file). This is great, but when using Mongoid, we have to use the &lt;a href=&quot;https://github.com/meskyanichi/mongoid-paperclip&quot;&gt;mongoid-paperclip&lt;/a&gt; gem, which does not support these matchers. I did some research on Google and Stackoverflow, but I could not find a clear cut answer. So what I decided to do was just test if the object had the Paperclip fields defined and were set. When you define a Paperclip attachment in a model, it will create several fields for you. For example, if my Paperclip attachment is called :banner_image, then it will create the following fields in your model automatically: :banner_image_file_name, :banner_image_content_type, :banner_image_file_size, and :banner_image_updated_at; I wanted to test to make sure that these fields were not nil. Now you can just put these checks directly in to your test, but I wanted to be able to reuse these file checks without copying and pasting code. We can do this with something called RSpec Matchers, which allow you to define conditions that get tested after the should method. I won&#39;t go in to too much detail about them here, but you can watch &lt;a href=&quot;http://railscasts.com/episodes/157-rspec-matchers-macros&quot;&gt;this&lt;/a&gt; Railscasts for more information. I created a file called banner_image_matcher.rb in Rails.root/spec/support/matchers and put this inside:&lt;br /&gt;
&lt;pre name=&quot;code&quot; class=&quot;rails&quot;&gt;# An RSpec matcher used to test the banner_image file attachment of the Event model. It tests whether the Paperclip fields for file attachments exist or not.
RSpec::Matchers.define :have_banner_image_attached_file do |expected|
   match do |actual|
      actual.banner_image_file_name != nil &amp;amp;&amp;amp;
      actual.banner_image_content_type != nil &amp;amp;&amp;amp;
      actual.banner_image_file_size != nil &amp;amp;&amp;amp;
      actual.banner_image_updated_at != nil
   end

   failure_message_for_should do |actual|
      &quot;expected that #{actual} would have a banner_image file attachment&quot;
   end

   failure_message_for_should_not do |actual|
      &quot;expected that #{actual} would not have a banner_image file attachment&quot;
   end
end
&lt;/pre&gt;More detailed information can be found &lt;a href=&quot;https://github.com/dchelimsky/rspec/wiki/custom-matchers&quot;&gt;here&lt;/a&gt;, but basically inside the match block, you want to test your condition, and then return true or false. You can also modify the error messages that get printed when a test fails.&lt;br /&gt;
&lt;br /&gt;
Now we can finally write the test. Here is what I did:&lt;pre name=&quot;code&quot; class=&quot;rails&quot;&gt;it &quot;should assign a newly created event as @event with an image attachment&quot; do 
   event = FactoryGirl.create(:event, :banner_image =&amp;gt; File.new(Rails.root + &#39;spec/support/images/bannerTest.png&#39;))
   Event.stub(:new).and_return(event)

   post :create, :event =&amp;gt; event

   assigns(:event).should eq(event)
   assigns(:event).should have_banner_image_attached_file
end&lt;/pre&gt;Basically I do the same thing as my previous tests, but I add an extra check for the banner image using the RSpec matcher I just created. Also, I want to mention that you can provide a file to test with by reading one in using File.new. I put a test image in the Rails.root/spec/support/images folder and reference it there. This all works great, but there&#39;s on thing we&#39;re missing. If you&#39;re using Amazon S3 to upload your files to, these tests will actually upload your image every time you run your test. This is something we probably don&#39;t want to do, so we can prevent that from happening by stubbing out the method that uploads the file. That method is called save_attached_files, and we can stub it out by using the following code: Event.any_instance.stub(:save_attached_files).and_return(true). So now our test should look like this:&lt;pre name=&quot;code&quot; class=&quot;rails&quot;&gt;it &quot;should assign a newly created event as @event with an image attachment&quot; do 
   # stub out this method so that this test does not actually upload the image to amazon s3
   Event.any_instance.stub(:save_attached_files).and_return(true)

   event = FactoryGirl.create(:event, :banner_image =&amp;gt; File.new(Rails.root + &#39;spec/support/images/bannerTest.png&#39;))
   Event.stub(:new).and_return(event)

   post :create, :event =&amp;gt; event

   assigns(:event).should eq(event)
   assigns(:event).should have_banner_image_attached_file
end&lt;/pre&gt;We can run this test (or have Guard run it for us) and see that it passes. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;I hope that this post was helpful in getting started with RSpec testing, and also how to test with Paperclip and Mongoid. Feel free to ask questions in the comments and I will do by best to answer all of them.&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://paul-wong-jr.blogspot.com/feeds/7354711462508444315/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://paul-wong-jr.blogspot.com/2012/02/rails-31-testing-with-rspec-paperclip.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/924015769731377256/posts/default/7354711462508444315'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/924015769731377256/posts/default/7354711462508444315'/><link rel='alternate' type='text/html' href='http://paul-wong-jr.blogspot.com/2012/02/rails-31-testing-with-rspec-paperclip.html' title='Rails 3.1 testing with RSpec, Paperclip, and Mongoid'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-924015769731377256.post-4847664705543939816</id><published>2011-06-03T11:52:00.000-07:00</published><updated>2012-04-09T13:44:07.282-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ruby on rails 3 mysql2 windows 7 64bit"/><title type='text'>Getting mysql2 gem to work with Ruby on Rails 3.0 and Windows 7 64bit</title><content type='html'>&lt;div&gt;Edit: For Rails 3.1, these same steps should still work. I had some issues at first, but try uninstalling (gem uninstall mysql2 -a) all previous instances of the mysql2 gem before installing the latest one.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;The &lt;a href=&quot;https://github.com/brianmario/mysql2&quot;&gt;mysql2 gem&lt;/a&gt; recently added support for Windows (&lt;a href=&quot;https://github.com/brianmario/mysql2/issues/8&quot;&gt;https://github.com/brianmario/mysql2/issues/8&lt;/a&gt;), but it sure was a pain in the ass to install. Hopefully this blog post will help save you the time and swearing that this gem has caused me. I had a lot of issues just trying to get the gem to talk with my MySQL server, and it seemed like there was some issues with using the 64bit version of MySQL server, so I eventually downgraded to the 32bit version. Also, you cannot just do a bundle install or gem install mysql2 to get this gem installed. Lastly, once I finally got the dam gem installed, it would always hang when I tried to use it (e.g. rake db:create), and I found that there&#39;s an issue on github here: &lt;a href=&quot;https://github.com/brianmario/mysql2/issues/142&quot;&gt;https://github.com/brianmario/mysql2/issues/142&lt;/a&gt;, but I was able to still make it work.&lt;br /&gt;&lt;br /&gt;First off, here are the versions of my software:&lt;div&gt;&lt;ul&gt;&lt;li&gt;Ruby 1.9.2p180 (2011-02-18) [i386-mingw32] installed from &lt;a href=&quot;http://rubyinstaller.org/&quot;&gt;RubyInstaller&lt;/a&gt;&lt;/li&gt;&lt;li&gt;RubyInstaller&#39;s DevKit: &lt;a href=&quot;http://github.com/downloads/oneclick/rubyinstaller/DevKit-tdm-32-4.5.1-20101214-1400-sfx.exe&quot;&gt;DevKit-tdm-32-4.5.1-20101214-1400-sfx.exe&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Rails 3.0.7 or 3.0.8RC2&lt;/li&gt;&lt;li&gt;MySQL Server 5.5 &lt;b&gt;32 bit&lt;/b&gt; (It&#39;s really important that you install the 32 bit version of MySQL because the 64 bit version doesn&#39;t play nice with RubyInstaller. Refer to here for more information: &lt;a href=&quot;https://github.com/oneclick/rubyinstaller/wiki/Troubleshooting#gems_mix_bits&quot;&gt;https://github.com/oneclick/rubyinstaller/wiki/Troubleshooting#gems_mix_bits&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Assuming you have all this already installed, here are the steps you need to follow:&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;Copy C:\Program Files (x86)\MySQL\MySQL Server 5.5\lib\libmysql.dll to C:\Ruby192\bin. I think also if you just add C:\Program Files (x86)\MySQL\MySQL Server 5.5\lib\ to your environment variables it might work too.&lt;/li&gt;&lt;li&gt;Uninstall all previous version of the mysql2 gem just in case. e.g. gem uninstall mysql2 -a&lt;/li&gt;&lt;li&gt;Go to the mysql2 github page and select the 0.2.x branch, then click the Downloads button to download the gem (or you can go here: https://github.com/brianmario/mysql2/zipball/0.2.x). We&#39;re going to have to manually compile and install the gem. The latest mysql2 version 0.3.x only works with Rails 3.1 and not 3.0.&lt;/li&gt;&lt;li&gt;Unzip in to a folder called mysql2-0.2.7 in your Ruby installation folder here: C:\Ruby192\lib\ruby\gems\1.9.1\gems, so that afterwards it looks like: C:\Ruby192\lib\ruby\gems\1.9.1\gems\mysql2-0.2.7&lt;/li&gt;&lt;li&gt;Now load up Git Bash (I couldn&#39;t get this to work in regular Command Prompt) and go to C:\Ruby192\lib\ruby\gems\1.9.1\gems\mysql2-0.2.7 and type: gem build mysql2.gemspec&lt;/li&gt;&lt;li&gt;Now you should have a file called mysql2-0.2.7.gem in your directory. Let&#39;s install the gem now. First type: subst X: &quot;C:\Program Files (x86)\MySQL\MySQL Server 5.5&quot; (or wherever your MySQL Server is installed).&lt;/li&gt;&lt;li&gt;Then type: gem install mysql2-0.2.7.gem --platform=ruby -- --with-mysql-dir=X: --with-mysql-lib=X:\lib&lt;/li&gt;&lt;li&gt;Congrats, you&#39;re done now! We can test it by typing rake db:create or rake db:migrate in one of your projects. If all went well you shouldn&#39;t have gotten any errors. Good luck!&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://paul-wong-jr.blogspot.com/feeds/4847664705543939816/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://paul-wong-jr.blogspot.com/2011/06/getting-mysql2-gem-to-work-with-ruby-on.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/924015769731377256/posts/default/4847664705543939816'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/924015769731377256/posts/default/4847664705543939816'/><link rel='alternate' type='text/html' href='http://paul-wong-jr.blogspot.com/2011/06/getting-mysql2-gem-to-work-with-ruby-on.html' title='Getting mysql2 gem to work with Ruby on Rails 3.0 and Windows 7 64bit'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry></feed>