tag:blog.juliantescher.com,2014:/feedJulian Tescher2014-12-15T10:05:08-08:00Julian Tescherhttp://blog.juliantescher.comSvbtle.comtag:blog.juliantescher.com,2014:Post/getting-started-with-scala-development2014-12-15T10:05:08-08:002014-12-15T10:05:08-08:00Getting Started With Scala Development<p><img src="https://jtescher.github.io/assets/getting-started-with-scala-development/scala-logo.png" alt="Scala Logo"></p>
<p>Learning new languages can be a great way to expand your skills and stay up to date with software development trends. The language that I’m currently learning is Scala! It’s a great language for picking up functional programming concepts, and it being on the JVM allows you to leverage the Java ecosystem’s libraries and frameworks. In this post I’ll show you how to install Scala and give you a few resources to get you started.</p>
<h1 id="installing-scala_1">Installing Scala <a class="head_anchor" href="#installing-scala_1">#</a>
</h1>
<p>To install Scala you need to install a <a href="https://www.java.com/en/">Java runtime</a> version 1.6 or later. Once you have that installed you can install Scala through <a href="http://brew.sh">homebrew</a> if you are on a mac, or follow <a href="http://scala-lang.org/download">these instructions</a> if you are not.</p>
<pre><code class="prettyprint lang-bash">$ brew install scala
</code></pre>
<h1 id="using-scala_1">Using Scala <a class="head_anchor" href="#using-scala_1">#</a>
</h1>
<p>You can get started playing with the language basics from the terminal with the <code class="prettyprint">scala</code> command.</p>
<pre><code class="prettyprint lang-bash">$ scala
Welcome to Scala version 2.11.4 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_25).
Type in expressions to have them evaluated.
Type :help for more information.
scala>
</code></pre>
<p>Here you can evaluate simple expressions and quickly try a few things (enter :quit to exit the REPL).</p>
<pre><code class="prettyprint lang-bash">scala> println("Hello world")
Hello world
scala>
</code></pre>
<h1 id="learning-scala_1">Learning Scala <a class="head_anchor" href="#learning-scala_1">#</a>
</h1>
<p>Scala has great free resources to get you up to speed quickly. I would recommend the following:</p>
<ul>
<li><p>The online course <a href="https://www.coursera.org/course/progfun">Functional Programming Principles in Scala</a> available on <br>
Coursera. This class is taught by the creator of Scala, Martin Odersky, and is a good overview of scala functional <br>
programming styles.</p></li>
<li><p>The <a href="https://www.coursera.org/course/reactive">Principles of Reactive Programming</a> course, also taught by <br>
Martin and goes into a lot of ways to create composable software that is event-driven, scalable under load, resilient <br>
and responsive in the presence of failures</p></li>
<li><p>The books <a href="http://www.artima.com/shop/programming_in_scala_2ed">Programming in Scala</a> and <a href="http://www.manning.com/raychaudhuri/">Scala in Action</a> which cover the language features in depth.</p></li>
<li><p>Also <a href="http://www.kogics.net/sf:kojo">Kojo</a> which is an interesting interactive learning environment.</p></li>
</ul>
tag:blog.juliantescher.com,2014:Post/writing-command-line-applications-in-ruby-with-thor2014-06-03T16:46:39-07:002014-06-03T16:46:39-07:00Writing Command Line Applications In Ruby With Thor<p>Writing small command line utilities and bash scripts can save you a lot of time as a developer. People often don’t take <br>
advantage of them though because they feel intimidated and confused by the ones they use every day like <code class="prettyprint">$ git status</code> <br>
or <code class="prettyprint">$ rails new</code> and it seems like there is just too much to learn. While it’s true that some utilities are pretty <br>
complicated, writing simple scripts is fairly painless and can help you greatly with repetitive tasks or when using an<br>
application that doesn’t need a graphical interface. </p>
<p>In this post I’ll show you how to create a simple calculator app/utility starting from in-line shell scripts in ruby and <br>
moving up to using the <a href="https://github.com/erikhuda/thor">Thor gem</a>. Even though my examples with Thor are pretty simple,<br>
it can be used to build quite powerful and expressive projects like the <a href="https://github.com/sferik/t">Twitter CLI</a> and <br>
the Rails CLI.</p>
<p>I’m going to use a simple calculator with just add and subtract functions as examples but they are just placeholders for<br>
whatever work you want to do. I’ll show how this functionality can be implemented in three versions: a simple inline <br>
version, a more complicated version with command line options, and finally a version that uses Thor.</p>
<h2 id="starting-small-inline-scripts_2">Starting Small: Inline scripts <a class="head_anchor" href="#starting-small-inline-scripts_2">#</a>
</h2>
<p>To get started, we want to be able to add a group of numbers and subtract a group of numbers. This is so simple that it<br>
can be expressed as a one line Ruby script and evaluated directly. The <code class="prettyprint">ruby</code> command lets you pass in arbitrary Ruby <br>
code that can be executed with the <code class="prettyprint">-e</code> flag. The simplest version of our program then would be to add numbers<br>
in Ruby and use <code class="prettyprint">puts</code> to print out the results:</p>
<pre><code class="prettyprint lang-bash">$ ruby -e "puts 2 + 2"
4
</code></pre>
<p>And we can implement our subtraction solution the same way:</p>
<pre><code class="prettyprint lang-bash">$ ruby -e "puts 11 - 6"
5
</code></pre>
<p>That’s pretty simple. If your needs can be fulfilled with that then there is no need to go on. But most requirements are<br>
not that basic. If you want to be able to let someone who does not understand Ruby use this then you want a simpler, <br>
more well-defined interface for them to use.</p>
<h2 id="adding-complexity-command-line-options_2">Adding Complexity: Command Line Options <a class="head_anchor" href="#adding-complexity-command-line-options_2">#</a>
</h2>
<p>A step up from having your code evaluated in-line would be to have a defined set of functions that a user could call, <br>
passing the arguments in from the terminal. This would allow them to find their answers without all the knowledge of <br>
how the results are calculated and returned.</p>
<p>To do this, you can save your methods to a file (call it whatever you like, I am going with <code class="prettyprint">calculator</code> for this <br>
example). Remember to make your file executable with <code class="prettyprint">$ chmod +x calculator</code>.</p>
<p>In Ruby all command line options are available to scripts as <code class="prettyprint">ARGV</code> so we can use this to allow options to be passed in. </p>
<p>Below are the two methods that will take the options and perform the operations on them (the first line just says that <br>
this file should be interpreted as ruby code):</p>
<pre><code class="prettyprint lang-ruby">#!/usr/bin/env ruby
def add(args)
puts args.map(&:to_f).inject(:+)
end
def subtract(args)
puts args.map(&:to_f).inject(:-)
end
send(ARGV.shift, ARGV) if ARGV.length
</code></pre>
<p>The two functions first convert the user input from strings, and then either sum with “+” or take the difference with <br>
“-”. The last line grabs the first argument as the name of the method to use and the rest of the arguments as the inputs.</p>
<p>Then you can execute this application passing in the arguments with:</p>
<pre><code class="prettyprint lang-bash">$ ./calculator add 1 2 3
6.0
</code></pre>
<pre><code class="prettyprint lang-bash">$ ./calculator subtract 10 6
4.0
</code></pre>
<p>This is still a very simple example, but you can see how this technique could be used to encapsulate more complicated <br>
ideas into scripts with cleaner interfaces.</p>
<p>However, once you want to package your application for others to use or develop lots of complicated options that need <br>
explaining and option parsing this can get messy and repetitive. I’ve found that the best way to create powerful and <br>
well documented applications and utilities in Ruby is to use Thor.</p>
<h2 id="creating-command-line-interfaces-with-thor_2">Creating Command Line Interfaces With Thor <a class="head_anchor" href="#creating-command-line-interfaces-with-thor_2">#</a>
</h2>
<p><a href="https://github.com/erikhuda/thor">Thor</a> is built exactly for the purpose of writing command line applications like<br>
this. Here is how it is described by the creators:</p>
<blockquote>
<p>Thor is a simple and efficient tool for building self-documenting command line utilities. It removes the pain of <br>
parsing command line options, writing “USAGE:” banners, and can also be used as an alternative to the Rake build tool. <br>
The syntax is Rake-like, so it should be familiar to most Rake users.</p>
</blockquote>
<p>You can install Thor with <code class="prettyprint">gem install thor</code>, and then replace your <code class="prettyprint">calculator</code> file with:</p>
<pre><code class="prettyprint lang-ruby">#!/usr/bin/env ruby
require 'thor'
class Calculator < Thor
desc "add ...ARGS", "Calculate the sum of all numbers in ARGS"
def add(*args)
say args.map(&:to_f).inject(:+)
end
desc "subtract ...ARGS", "Calculate the difference of all numbers in ARGS"
def subtract(*args)
say args.map(&:to_f).inject(:-)
end
end
Calculator.start(ARGV)
</code></pre>
<p>This should look very familiar by now, the difference is that you now have a class that inherits from Thor, and Thor <br>
will parse the options and build the output for you.</p>
<p>It also gives you a convenient way to list all options by passing no arguments when you execute calculator:</p>
<pre><code class="prettyprint lang-bash">$ ./calculator
Commands:
calculator add ...ARGS # Calculate the sum of all numbers in ARGS
calculator help [COMMAND] # Describe available commands or one specific command
calculator subtract ...ARGS # Calculate the difference of all numbers in ARGS
</code></pre>
<p>And you can pass in arguments as usual:</p>
<pre><code class="prettyprint lang-bash">$ ./calculator add 1 2 3
6.0
</code></pre>
<p>It is as simple as that. Thor gives you the power to create well documented and full-featured utilities simply and <br>
quickly. If you want to know more about Thor and all of it’s fancy features like sub commands you can go on to read the <br>
helpful <a href="http://whatisthor.com/">whatisthor.com</a> site.</p>
tag:blog.juliantescher.com,2014:Post/basic-rails-api-caching2014-05-27T12:34:52-07:002014-05-27T12:34:52-07:00Basic Rails API Caching<p>Rails performance out of the box is acceptable for prototypes and small applications with limited traffic. However as <br>
your application grows in popularity you will inevitably be faced with the decision to either add more servers, or use<br>
your existing servers more efficiently. Complex caching strategies can be incredibly difficult to implement correctly,<br>
but simple caching layers can go a long way.</p>
<p>In this post I’ll explain two basic Rails caching mechanisms and explain some of the costs and benefits of each.</p>
<h2 id="http-caching_2">HTTP Caching <a class="head_anchor" href="#http-caching_2">#</a>
</h2>
<p>If your API responses are mostly static content like a list of available products, then <br>
<a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html">HTTP Caching</a> can be a very effective solution. Even something<br>
as low as a one minute cache can move the vast majority of your requests to a CDN like<br>
<a href="https://www.cloudflare.com/">CloudFlare</a> or an in-memory store like<br>
<a href="http://rtomayko.github.io/rack-cache/">rack cache</a>.</p>
<p>Specifying the expiration time is simple. In your controller action just call <code class="prettyprint">expires_in</code> with the time:</p>
<pre><code class="prettyprint lang-ruby">class ProductsController < ApplicationController
def index
expires_in 1.minute, public: true
@products = Product.all
end
end
</code></pre>
<p>This will result in a header being set to <code class="prettyprint">Cache-Control: max-age=60, public</code> which any CDN will pick up and serve for<br>
you instead of the request hitting your server.</p>
<p>This solution works well when the content is mostly static but it comes with the downside that changes to your content<br>
will not be seen for up to one minute (or whichever time you have chosen).</p>
<h2 id="conditional-get_2">Conditional GET <a class="head_anchor" href="#conditional-get_2">#</a>
</h2>
<p>Another option is using ETags or Last-Modified times to know what version of the resource the client has last seen and <br>
returning a HTTP <code class="prettyprint">304 Not Modified</code> response with no content if the resource has not changed.</p>
<p>To set this up in a controller you can either use the<br>
<a href="http://api.rubyonrails.org/classes/ActionController/ConditionalGet.html#method-i-fresh_when">fresh_when</a> or <br>
<a href="http://api.rubyonrails.org/classes/ActionController/ConditionalGet.html#method-i-stale-3F">stale?</a> methods. Here is an <br>
example using the <code class="prettyprint">fresh_when</code> method.</p>
<pre><code class="prettyprint lang-ruby">class ProductsController < ApplicationController
def show
@product = Product.find(params[:id])
fresh_when(etag: @product, last_modified: @product.created_at, public: true)
end
end
</code></pre>
<p>This method attaches an <code class="prettyprint">ETag</code> header and a <code class="prettyprint">Last-Modified</code> header to every product response. Now if you make a request <br>
for a given product you will see the headers in the response:</p>
<pre><code class="prettyprint lang-bash">curl -i localhost:3000/products/1.json
HTTP/1.1 200 OK
ETag: "91206795ac4c5cd1b02d8fcbc752b97a"
Last-Modified: Mon, 27 May 2014 09:00:00 GMT
...
</code></pre>
<p>And if you make the same request but include the ETag in a <code class="prettyprint">If-None-Match</code> header, the server can return 304 with empty<br>
content and save all the time it would have spent rendering the content.</p>
<pre><code class="prettyprint lang-bash">curl -i localhost:3000/products/1.json \
--header 'If-None-Match: "91206795ac4c5cd1b02d8fcbc752b97a"'
HTTP/1.1 304 Not Modified
Etag: "91206795ac4c5cd1b02d8fcbc752b97a"
Last-Modified: Mon, 27 May 2014 09:00:00 GMT
...
</code></pre>
<p>The other option is to use the <code class="prettyprint">If-Modified-Since</code> header in the request, which will have the same result:</p>
<pre><code class="prettyprint lang-bash">curl -i localhost:3000/products/1.json \
--header 'If-Modified-Since: Mon, 27 May 2014 09:00:00 GMT'
HTTP/1.1 304 Not Modified
Etag: "91206795ac4c5cd1b02d8fcbc752b97a"
Last-Modified: Mon, 27 May 2014 09:00:00 GMT
...
</code></pre>
<p>This method still requires a request to be made to the Rails app, and the product still has to be pulled from the <br>
database to determine the <code class="prettyprint">created_at</code> time. However, rendering the response body can be a substantial portion of<br>
each server response so this is a simple way to save a lot of time.</p>
<p>These examples are only the beginning of the caching options Rails offers. As of Rails 4<br>
<a href="https://github.com/rails/actionpack-page_caching">page caching</a> as well as <br>
<a href="https://github.com/rails/actionpack-action_caching">action caching</a> have been pulled out into their own gems and are <br>
worth looking at if you need those options.</p>
<p>Finally if you are ready for something a little more robust you can read about Basecamp’s <br>
<a href="http://signalvnoise.com/posts/3113-how-key-based-cache-expiration-works">Russian Doll Caching</a> to see how they solve<br>
these problems.</p>
tag:blog.juliantescher.com,2014:Post/building-a-go-web-app-with-revel-on-heroku2014-05-12T11:30:40-07:002014-05-12T11:30:40-07:00Building A Go Web App with Revel on Heroku<p>I’ve been interested in Go for a long time now. The language has lots of aspects that make it well suited for building<br>
modern web applications including its powerful <a href="http://golang.org/pkg/">standard library</a>, concurrency primitives, and<br>
impressive <a href="http://www.techempower.com/benchmarks">performance benchmarks</a>. The community is also gaining a lot of<br>
ground in terms of tooling, web frameworks, and other resources for creating sites in Go.</p>
<p>In this post I will show you how to create a basic app in Go and how to host it on <a href="https://www.heroku.com/">Heroku</a>.</p>
<p>If you do not have Go installed on your system, you can do so on a mac with <code class="prettyprint">$ brew install go</code> or follow the<br>
instructions <a href="http://golang.org/doc/install">here</a>. Also if you’re interested in learning the basics of Go,<br>
be sure to check out <a href="http://tour.golang.org/">A Tour of Go</a>.</p>
<p>If you get stuck you can find all of the code for this post at<br>
<a href="https://github.com/jtescher/example-revel-app">github.com/jtescher/example-revel-app</a>.</p>
<h2 id="creating-a-revel-app_2">Creating a Revel App <a class="head_anchor" href="#creating-a-revel-app_2">#</a>
</h2>
<p><a href="http://revel.github.io/"><img src="https://jtescher.github.io/assets/building-a-go-web-app-with-revel-on-heroku/revel-logo.png" alt="Revel Logo"></a></p>
<p>Revel is a high-productivity web framework for the Go language. It has an impressive feature set and is much more in<br>
line with the rails “convention over configuration” approach than most other Go web frameworks.</p>
<p>To get the project started, first install Revel into your <code class="prettyprint">$GOPATH</code>:</p>
<pre><code class="prettyprint lang-bash">$ go get github.com/revel/cmd/revel
</code></pre>
<p>Then we can create a new app with the <code class="prettyprint">revel new</code> command. Remember you should use your own github username below:</p>
<pre><code class="prettyprint lang-bash">$ revel new github.com/jtescher/blog
</code></pre>
<p>And we can start up the app using the <code class="prettyprint">revel run</code> command. Again use your github usename, not mine.</p>
<pre><code class="prettyprint lang-bash">$ revel run github.com/jtescher/blog
~
~ revel! http://robfig.github.com/revel
~
INFO 2014/05/11 16:50:10 revel.go:292: Loaded module static
INFO 2014/05/11 16:50:10 revel.go:292: Loaded module testrunner
INFO 2014/05/11 16:50:10 run.go:57: Running blog (github.com/jtescher/blog) in dev mode
INFO 2014/05/11 16:50:10 harness.go:157: Listening on :9000
INFO 2014/05/11 16:50:23 revel.go:292: Loaded module testrunner
INFO 2014/05/11 16:50:23 revel.go:292: Loaded module static
INFO 2014/05/11 16:50:23 main.go:29: Running revel server
Go to /@tests to run the tests.
</code></pre>
<p>Now you can go to <a href="http://localhost:9000/">localhost:9000</a> and you should see the welcome page.</p>
<p><img src="https://jtescher.github.io/assets/building-a-go-web-app-with-revel-on-heroku/revel-welcome.png" alt="Revel Welcome Page"></p>
<h2 id="serving-content-from-revel_2">Serving Content From Revel <a class="head_anchor" href="#serving-content-from-revel_2">#</a>
</h2>
<p>Revel has an easily understood MVC structure and ships with bootstrap by default. You can read more about the flow of<br>
control through a Revel app in their excellent <a href="http://revel.github.io/manual/concepts.html">core concepts</a><br>
documentation, but for now let’s just render some custom content by adjusting the <code class="prettyprint">App/index.html</code> view. Revel uses Go’s<br>
built in templating for HTML rendering.</p>
<pre><code class="prettyprint lang-html"><!-- app/views/App/index.html -->
{{set . "title" "Home"}}
{{template "header.html" .}}
<div class="container">
<div class="hero-unit">
<h1>Hello from Revel!</h1>
<p>Creating HTML pages is very straightforward.</p>
<p><a class="btn btn-primary btn-large" role="button">Awesome</a></p>
</div>
<div class="row">
<div class="span6">
{{template "flash.html" .}}
</div>
</div>
</div>
{{template "footer.html" .}}
</code></pre>
<p>And if you reload the page you should see your changes.</p>
<p><img src="https://jtescher.github.io/assets/building-a-go-web-app-with-revel-on-heroku/custom-revel-content.png" alt="Custom Revel Content"></p>
<h2 id="deploying-the-app_2">Deploying The App <a class="head_anchor" href="#deploying-the-app_2">#</a>
</h2>
<p>Deploying a Revel app to Heroku is quite simple. First we create a <code class="prettyprint">.godir</code> file at the root of our project with the<br>
path to the project in it.</p>
<pre><code class="prettyprint lang-bash">$ echo "github.com/jtescher/blog" > .godir
</code></pre>
<p>Then we can create the app on Heroku using a buildpack.</p>
<pre><code class="prettyprint lang-bash">$ heroku create -b https://github.com/robfig/heroku-buildpack-go-revel.git
</code></pre>
<p>And finally we can push our app to Heroku.</p>
<pre><code class="prettyprint lang-bash">$ git push heroku
$ heroku open
</code></pre>
<p>And that’s it! Your Revel app should now be live.</p>
tag:blog.juliantescher.com,2014:Post/creating-a-metrics-dashboard-with-ember-and-rails-part-three2014-04-28T11:28:09-07:002014-04-28T11:28:09-07:00Creating A Metrics Dashboard With Ember.js, Bootstrap, and Rails - Part 3<p><em>This is part three of a series on building a metrics dashboard with Ember, Bootstrap, and Rails. Over the next few weeks<br>
I will be building out more functionality and writing posts to cover that. If you haven’t read<br>
<a href="/creating-a-metrics-dashboard-with-ember-bootstrap-and-rails-part-one">part one</a> and<br>
<a href="/creating-a-metrics-dashboard-with-emberjs-bootstrap-and-rails-part-two">part two</a> then that’s a good place to start.</em></p>
<p>In <a href="/creating-a-metrics-dashboard-with-emberjs-bootstrap-and-rails-part-two">part two</a> we ended up with an Ember app that rendered<br>
dynamic tables. If you followed along, your page should now look like this:</p>
<p><img src="https://jtescher.github.io/assets/creating-a-metrics-dashboard-with-ember-and-rails-part-two/currency-helpers.png" alt="Part Two Final"></p>
<p>Today we’re going to add some graphs and see how Ember components work.</p>
<p>Remember, if you get stuck you can find all of the code for this post at<br>
<a href="https://github.com/jtescher/example-ember-rails-dashboard">github.com/jtescher/example-ember-rails-dashboard</a>.</p>
<h2 id="choosing-the-right-library_2">Choosing The Right Library <a class="head_anchor" href="#choosing-the-right-library_2">#</a>
</h2>
<p><a href="http://www.highcharts.com/demo/combo/"><img src="http://jtescher.github.io/assets/creating-a-metrics-dashboard-with-ember-and-rails-part-three/highcharts-demo.png" alt="Highcharts Demo"></a></p>
<p>There are many good options when it comes to JavaScript graphing, charting, and visualizations. I find<br>
<a href="http://www.highcharts.com/">highcharts</a> to be a good place to get started and it is free for non-commercial uses!<br>
If you find yourself needing more control or having a very specific requirement you can always look at projects like<br>
<a href="http://d3js.org/">d3.js</a>.</p>
<h2 id="adding-highcharts_2">Adding Highcharts <a class="head_anchor" href="#adding-highcharts_2">#</a>
</h2>
<p>Let’s download the latest version of highcharts to our <code class="prettyprint">vendor/assets/javascripts</code> directory.</p>
<pre><code class="prettyprint lang-bash">$ curl http://code.highcharts.com/4.0.1/highcharts.js \
-o vendor/assets/javascripts/highcharts-4.0.1.js
</code></pre>
<p>And then require the file in <code class="prettyprint">app/assets/javascripts/application.js</code></p>
<pre><code class="prettyprint lang-js">...
//= require jquery
//= require accounting-0.3.2
//= require highcharts-4.0.1
//= require_tree .
</code></pre>
<h2 id="creating-the-ember-component_2">Creating The Ember Component <a class="head_anchor" href="#creating-the-ember-component_2">#</a>
</h2>
<p>Ember makes adding reusable components quite simple. We can add a component that represents a specific chart we want to<br>
show on the screen and have ember re-render the chart whenever the data changes. You can read more about how the Ember<br>
components work <a href="http://emberjs.com/guides/components/">here</a>.</p>
<p>As an example we can add a highcharts column chart to show revenue by product. First let’s add the component in our<br>
<code class="prettyprint">app/assets/javascripts/templates/orders.hbs</code> file:</p>
<pre><code class="prettyprint lang-html"><h1>Orders</h1>
{{column-chart chartId='revenue-by-product'}}
<table class='table table-striped'>
...
</code></pre>
<p>Then we can add the template for the component in <code class="prettyprint">app/assets/javascripts/templates/components/column-chart.hbs</code>:</p>
<pre><code class="prettyprint lang-html"><div {{bind-attr id='chartId'}} style='width: 100%;'></div>
</code></pre>
<p>And finally we can define the component in <code class="prettyprint">app/assets/javascripts/components/column-chart.js.coffee</code>:</p>
<pre><code class="prettyprint lang-coffeescript">Dashboard.ColumnChartComponent = Ember.Component.extend
tagName: 'div'
classNames: ['highcharts']
contentChanged: (->
@rerender()
).observes('series')
didInsertElement: ->
$("##{@chartId}").highcharts({
chart: { type: 'column' },
title: { text: 'Revenue by Product' },
legend: { enabled: false },
xAxis: {
title: {
text: 'Product Number'
}
},
series: [{
name: 'Quantity',
data: [4, 4]
}, {
name: 'Revenue',
data: [10.0, 10.0]
}]
})
willDestroyElement: ->
$("##{@chartId}").highcharts().destroy()
</code></pre>
<p>Then when you reload the page it should look like this:</p>
<p><img src="http://jtescher.github.io/assets/creating-a-metrics-dashboard-with-ember-and-rails-part-three/orders-static-column-chart.png" alt="Orders Static Column Chart"></p>
<h2 id="binding-data-to-the-ember-component_2">Binding Data To The Ember Component <a class="head_anchor" href="#binding-data-to-the-ember-component_2">#</a>
</h2>
<p>The chart we have is currently always showing the same series because we hard coded it in the component. Let’s now make<br>
this dynamic by adding the data in the route and using data bindings.</p>
<p>First let’s update the data in our orders route to include a product id.</p>
<pre><code class="prettyprint lang-coffeescript"># app/assets/javascripts/routes/orders_route.js.coffee
Dashboard.OrdersRoute = Ember.Route.extend({
model: ->
[
{
id: 1,
firstName: 'James',
lastName: 'Deen',
quantity: 1,
revenue: '10.00',
productId: 0,
},
{
id: 2,
firstName: 'Alex',
lastName: 'Baldwin',
quantity: 2,
revenue: '20.00',
productId: 1,
}
]
})
</code></pre>
<p>And then we can build our chart series in the orders controller (this is a very simplistic example):</p>
<pre><code class="prettyprint lang-coffeescript">Dashboard.OrdersController = Ember.ArrayController.extend({
...
chartSeries: (->
revenues = @map((order)->
parseFloat(order.revenue)
)
quantities = @mapBy('quantity')
[
{
name: 'Quantity',
data: quantities
},
{
name: 'Revenue',
data: revenues
}
]
).property('@each')
})
</code></pre>
<p>We can then bind <code class="prettyprint">chartSeries</code> in <code class="prettyprint">orders.hbs</code>:</p>
<pre><code class="prettyprint lang-html"><h1>Orders</h1>
{{column-chart chartId='revenue-by-product' series=chartSeries}}
<table class='table table-striped'>
</code></pre>
<p>And finally use series in our chart component:</p>
<pre><code class="prettyprint lang-coffeescript"># app/assets/javascripts/components/column-chart.js.coffee
...
didInsertElement: ->
$("##{@chartId}").highcharts({
chart: { type: 'column' },
title: { text: 'Revenue by Product' },
legend: { enabled: false },
xAxis: {
title: {
text: 'Product Number'
}
},
series: @series
})
...
</code></pre>
<p>We then end up with our final dynamic chart rendered by Ember:<br>
<img src="http://jtescher.github.io/assets/creating-a-metrics-dashboard-with-ember-and-rails-part-three/orders-dynamic-column-chart.png" alt="Orders Static Column Chart"></p>
tag:blog.juliantescher.com,2014:Post/creating-a-metrics-dashboard-with-emberjs-bootstrap-and-rails-part-two2014-04-21T11:13:16-07:002014-04-21T11:13:16-07:00Creating A Metrics Dashboard With Ember.js, Bootstrap, and Rails - Part 2<p><em>This is part two of a series on building a metrics dashboard with Ember, Bootstrap, and Rails. Over the next few weeks<br>
I will be building out more functionality and writing posts to cover that. If you haven’t read<br>
<a href="/creating-a-metrics-dashboard-with-ember-bootstrap-and-rails-part-one">part one</a> then that’s a good place to start. You can find<br>
part three <a href="/creating-a-metrics-dashboard-with-ember-and-rails-part-three">here</a> when you are finished.</em> </p>
<p>In <a href="/creating-a-metrics-dashboard-with-ember-bootstrap-and-rails-part-one">part one</a> we ended up with a Rails app that generated<br>
the Ember app that rendered our metrics page. If you followed along your page should now look like this:</p>
<p><img src="https://jtescher.github.io/assets/creating-a-metrics-dashboard-with-ember-and-rails-part-one/ember-home-screen.png" alt="Part One Final"></p>
<p>Today we’re going to add some tables and see how data flows through an Ember app. If you are not familiar with Ember’s<br>
conventions and idioms you should first read their<br>
<a href="http://emberjs.com/guides/concepts/core-concepts/">excellent documentation and guides</a> before continuing here.</p>
<p>Remember, if you get stuck you can find all of the code for this post at<br>
<a href="https://github.com/jtescher/example-ember-rails-dashboard">github.com/jtescher/example-ember-rails-dashboard</a>.</p>
<h2 id="preparing-the-application_2">Preparing the application <a class="head_anchor" href="#preparing-the-application_2">#</a>
</h2>
<p>Before we add any more content let’s update our Ember application template and add a basic structure with some<br>
navigation in <code class="prettyprint">app/assets/javascripts/templates/application.hbs</code>.</p>
<pre><code class="prettyprint lang-html"><div class='container'>
<header class='masthead'>
<nav class='navbar navbar-default' role='navigation'>
<div class='container-fluid'>
<div class='navbar-header'>
<button type='button' class='navbar-toggle'
data-toggle='collapse' data-target='#main-nav-collapse'>
<span class='sr-only'>Toggle navigation</span>
<span class='icon-bar'></span>
<span class='icon-bar'></span>
<span class='icon-bar'></span>
</button>
{{#link-to 'application' class='navbar-brand'}}Dashboard{{/link-to}}
</div>
<div class='collapse navbar-collapse' id='main-nav-collapse'>
<ul class='nav navbar-nav'>
{{#link-to 'index' tagName='li' activeClass='active'}}
{{#link-to 'index'}}Home{{/link-to}}
{{/link-to}}
</ul>
</div>
</div>
</nav>
</header>
<section class='main-content'>
{{outlet}}
</section>
</div>
</code></pre>
<p>And let’s add an index template so we know when we’re on the home page in <code class="prettyprint">app/assets/javascripts/templates/index.hbs</code>.</p>
<pre><code class="prettyprint lang-html"><div class='jumbotron'>
<h1>Hello from Ember.js!</h1>
<p>Let's see some metrics.</p>
</div>
</code></pre>
<p>If you reload the page you should now see this:</p>
<p><img src="https://jtescher.github.io/assets/creating-a-metrics-dashboard-with-ember-and-rails-part-two/ember-home-screen.png" alt="Ember application template"></p>
<h2 id="creating-tables-with-ember-and-handlebars_2">Creating Tables with Ember and Handlebars <a class="head_anchor" href="#creating-tables-with-ember-and-handlebars_2">#</a>
</h2>
<p>Often the simplest way to display metrics data is to just put it all in a table. I find that it is often helpful<br>
when creating HTML with JavaScript to first start out with the final result and slowly add dynamic content in pieces.<br>
Let’s create an example of this to display some financial data about our sales process.</p>
<p>Step one is to create the Ember route to get to this URL. Let’s edit <code class="prettyprint">app/assets/javascripts/router.js.coffee</code> and add it:</p>
<pre><code class="prettyprint lang-coffeescript"># app/assets/javascripts/router.js.coffee
Dashboard.Router.map ()->
@resource('orders')
</code></pre>
<p>And we can then create an idea of what we want the page to look like by mocking up some static HTML in <code class="prettyprint">app/assets/javascripts/templates/orders.hbs</code></p>
<pre><code class="prettyprint lang-html"><h1>Orders</h1>
<table class='table table-striped'>
<tr>
<th>#</th>
<th>First Name</th>
<th>Last Name</th>
<th>Quantity</th>
<th>Revenue</th>
</tr>
<tr>
<td>1</td>
<td>James</td>
<td>Deen</td>
<td>1</td>
<td>$10.00</td>
</tr>
<tr>
<td>2</td>
<td>Alex</td>
<td>Baldwin</td>
<td>2</td>
<td>$20.00</td>
</tr>
</table>
<p>Total Quantity: <b>3</b></p>
<p>Total Revenue: <b>$30</b></p>
</code></pre>
<p>Then we can add a link to this page in our <code class="prettyprint">application.hbs</code> file (the double link-to is an annoying hack but<br>
explained <a href="https://github.com/emberjs/ember.js/issues/4387">here</a>):</p>
<pre><code class="prettyprint lang-html">...
<div class='collapse navbar-collapse' id='main-nav-collapse'>
<ul class='nav navbar-nav'>
{{#link-to 'index' tagName='li' activeClass='active'}}
{{#link-to 'index'}}Home{{/link-to}}
{{/link-to}}
{{#link-to 'orders' tagName='li' activeClass='active'}}
{{#link-to 'orders'}}Orders{{/link-to}}
{{/link-to}}
</ul>
</div>
...
</code></pre>
<p>Then if you reload and follow the orders nav link you should see this:</p>
<p><img src="https://jtescher.github.io/assets/creating-a-metrics-dashboard-with-ember-and-rails-part-two/orders-screen.png" alt="Static Orders"></p>
<h2 id="creating-dynamic-tables_2">Creating Dynamic Tables <a class="head_anchor" href="#creating-dynamic-tables_2">#</a>
</h2>
<p>In Ember, a template typically retrieves information to display from a controller, and the controller is set up by its<br>
route. Let’s make this table dynamic by assigning the data required to build it in the <code class="prettyprint">OrdersRoute</code>.</p>
<pre><code class="prettyprint lang-coffeescript"># app/assets/javascripts/routes/orders_route.js.coffee
Dashboard.OrdersRoute = Ember.Route.extend({
model: ->
[
{
id: 1,
firstName: 'James',
lastName: 'Deen',
quantity: 1,
revenue: '10.00',
},
{
id: 2,
firstName: 'Alex',
lastName: 'Baldwin',
quantity: 2,
revenue: '20.00',
}
]
})
</code></pre>
<p>And then we set up the controller to process the totals in the <code class="prettyprint">OrdersController</code>.</p>
<pre><code class="prettyprint lang-coffeescript"># app/assets/javascripts/controllers/orders_controller.js.coffee
Dashboard.OrdersController = Ember.ArrayController.extend({
totalQuantity: (->
@reduce(((previousValue, order) ->
previousValue + order.quantity
), 0)
).property('@each')
totalRevenue: (->
@reduce(((previousValue, order) ->
previousValue + parseFloat(order.revenue)
), 0)
).property('@each')
})
</code></pre>
<p>And this lets us use the data provided by the controller in the template:</p>
<pre><code class="prettyprint lang-html"><h1>Orders</h1>
<table class='table table-striped'>
<tr>
<th>#</th>
<th>First Name</th>
<th>Last Name</th>
<th>Quantity</th>
<th>Revenue</th>
</tr>
{{#each}}
<tr>
<td>{{id}}</td>
<td>{{firstName}}</td>
<td>{{lastName}}</td>
<td>{{quantity}}</td>
<td>{{revenue}}</td>
</tr>
{{/each}}
</table>
<p>Total Quantity: <b>{{totalQuantity}}</b></p>
<p>Total Revenue: <b>{{totalRevenue}}</b></p>
</code></pre>
<p>If you reload the page it should now look like this:</p>
<p><img src="https://jtescher.github.io/assets/creating-a-metrics-dashboard-with-ember-and-rails-part-two/dynamic-orders-screen.png" alt="Dynamic Orders"></p>
<h2 id="formatting-values-with-helpers_2">Formatting Values With Helpers <a class="head_anchor" href="#formatting-values-with-helpers_2">#</a>
</h2>
<p>The image above looks pretty good but we seem to have lost our currency formatting. There are a few good libraries for<br>
formatting currencies in JavaScript, and Ember makes it simple to access these libraries in your handlebars templates.<br>
Let’s add the <a href="http://josscrowcroft.github.io/accounting.js/">accounting.js</a> library to format our revenue numbers.</p>
<p>First install the library to <code class="prettyprint">vendor/assets/javascripts</code>:</p>
<pre><code class="prettyprint lang-bash">$ curl https://raw.github.com/josscrowcroft/accounting.js/master/accounting.js -o vendor/assets/javascripts/accounting-0.3.2.js
</code></pre>
<p>Then include it in your <code class="prettyprint">application.js</code> file:</p>
<pre><code class="prettyprint lang-javascript">//= require jquery
//= require accounting-0.3.2
//= require_tree .
</code></pre>
<p>Then create a <code class="prettyprint">currency_helpers.js.coffee</code> file to wrap the library.</p>
<pre><code class="prettyprint lang-coffeescript"># app/assets/javascripts/helpers/currency_helpers.js.coffee
Ember.Handlebars.registerBoundHelper('numberToCurrency', (number) ->
accounting.formatMoney(number)
)
</code></pre>
<p>And finally we can use this helper in our <code class="prettyprint">orders.hbs</code> view:</p>
<pre><code class="prettyprint lang-html">...
{{#each}}
<tr>
<td>{{id}}</td>
<td>{{firstName}}</td>
<td>{{lastName}}</td>
<td>{{quantity}}</td>
<td>{{numberToCurrency revenue}}</td>
</tr>
{{/each}}
</table>
<p>Total Quantity: <b>{{totalQuantity}}</b></p>
<p>Total Revenue: <b>{{numberToCurrency totalRevenue}}</b></p>
</code></pre>
<p>Now that our numbers are formatted properly you can reload the page and see our final result for part 2:</p>
<p><img src="https://jtescher.github.io/assets/creating-a-metrics-dashboard-with-ember-and-rails-part-two/currency-helpers.png" alt="Currency Helpers"></p>
<p>You can now go on to <a href="/creating-a-metrics-dashboard-with-ember-and-rails-part-three">part three</a> and start adding some<br>
charts!</p>
tag:blog.juliantescher.com,2014:Post/creating-a-metrics-dashboard-with-ember-bootstrap-and-rails-part-one2014-04-07T11:52:09-07:002014-04-07T11:52:09-07:00Creating A Metrics Dashboard With Ember.js, Bootstrap, and Rails - Part 1<p><em>This is part one of a series on building a metrics dashboard with Ember, Bootstrap, and Rails. Over the next few weeks<br>
I will be building out more functionality and writing posts to cover that. You can find part two<br>
<a href="/creating-a-metrics-dashboard-with-emberjs-bootstrap-and-rails-part-two">here</a>.</em></p>
<p>There are some services that will provide dashboards and visualizations for you like<br>
<a href="http://www.geckoboard.com/">Geckoboard</a>, but once you need to provide custom analytics and graphs to clients or<br>
co-workers you will need something a little more flexible.</p>
<p>Today we’re going to assemble the first pieces of this app by creating a Rails server, an Ember.js App and some basic<br>
Bootstrap styling.</p>
<p>You can find all of the code for this post at<br>
<a href="https://github.com/jtescher/example-ember-rails-dashboard">github.com/jtescher/example-ember-rails-dashboard</a>.</p>
<h2 id="the-rails-server_2">The Rails Server <a class="head_anchor" href="#the-rails-server_2">#</a>
</h2>
<p>We want to be able to expose all of our stats from various internal and third party services with a consistent API so<br>
this server will primarily handle authentication and data transformation. This server could just as easily be written<br>
in <a href="http://nodejs.org/">Node.js</a> or any language/framework, but for now we’ll stick with Rails.</p>
<p>Create the server (skipping ActiveRecord and TestUnit because we don’t need a database for this app and we will be<br>
testing with Rspec):</p>
<pre><code class="prettyprint lang-bash">$ rails new dashboard --skip-test-unit --skip-active-record
</code></pre>
<p>Then we want to add the route that will render our dashboard. We will use the home controller and the index action:</p>
<pre><code class="prettyprint lang-bash">$ rails generate controller Home index --no-helper --no-assets
</code></pre>
<p>We wil route everything to Ember, so replace your <code class="prettyprint">config/routes.rb</code> file with the following:</p>
<pre><code class="prettyprint lang-ruby"># config/routes.rb
Rails.application.routes.draw do
root 'home#index'
end
</code></pre>
<p>If you start your server now with <code class="prettyprint">$ rails server</code> and open up <a href="http://localhost:3000">localhost:3000</a> you should see<br>
the following:</p>
<p><img src="https://jtescher.github.io/assets/creating-a-metrics-dashboard-with-ember-and-rails-part-one/home-screen.png" alt="Home screen"></p>
<h2 id="the-theme_2">The Theme <a class="head_anchor" href="#the-theme_2">#</a>
</h2>
<p>We will be using stock <a href="http://getbootstrap.com/">Twitter Bootstrap</a> for this project so let’s add the <code class="prettyprint">bootstrap-sass</code><br>
gem to our <code class="prettyprint">Gemfile</code>.</p>
<pre><code class="prettyprint lang-ruby">...
# Front-end framework for developing responsive, mobile first projects on the web.
gem 'bootstrap-sass', '~> 3.1.1'
</code></pre>
<p>And configure it by creating a <code class="prettyprint">bootstrap_config.css.scss</code> file.</p>
<pre><code class="prettyprint lang-sass">// app/assets/stylesheets/bootstrap_config.css.scss
@import "bootstrap";
</code></pre>
<p>Then we can change the <code class="prettyprint">home/index.html.erb</code> view to the following:</p>
<pre><code class="prettyprint lang-html"><div class='container'>
<div class='jumbotron'>
<h1>Hello from Twitter Bootstrap!</h1>
<p>Lots of predefined style that makes things easy to prototype!</p>
</div>
</div>
</code></pre>
<p>And when you restart the server you should see:</p>
<p><img src="https://jtescher.github.io/assets/creating-a-metrics-dashboard-with-ember-and-rails-part-one/bootstrap-defaults.png" alt="Bootstrap Defaults"></p>
<h2 id="the-emberjs-app_2">The Ember.js App <a class="head_anchor" href="#the-emberjs-app_2">#</a>
</h2>
<p>We can now add the <code class="prettyprint">ember-rails</code> and <code class="prettyprint">ember-source</code> gems for Ember assets and scaffolding to our <code class="prettyprint">Gemfile</code>.</p>
<pre><code class="prettyprint lang-ruby">...
# JS framework for creating ambitious web applications.
gem 'ember-rails', '~> 0.14.1'
gem 'ember-source', '~> 1.5.0'
</code></pre>
<p>And install the Ember assets with:</p>
<pre><code class="prettyprint lang-bash">$ rails generate ember:bootstrap
</code></pre>
<p>We can also remove turbolinks as ember will handle all the routing after the first page load. Your <code class="prettyprint">application.js</code> file<br>
should look like this:</p>
<pre><code class="prettyprint lang-js">//= require jquery
//= require_tree .
</code></pre>
<p>I also renamed the generated <code class="prettyprint">app/assets/javascripts/application.js.coffee</code> file to be<br>
<code class="prettyprint">app/assets/javascripts/app.js.coffee</code> to not conflict with the first application.js file.</p>
<p>Next move the html from <code class="prettyprint">home/index.html.erb</code> and replace it with the following:</p>
<pre><code class="prettyprint lang-erb"><% # Rendered Entirely in EmberJS. See app/assets/javascripts %>
</code></pre>
<p>Then we can move the html generation to ember by placing it in the top level <code class="prettyprint">application.hbs</code> handlebars file.</p>
<pre><code class="prettyprint lang-html"><!-- app/assets/javascripts/templates/application.hbs -->
<div class='container'>
<div class='jumbotron'>
<h1>Hello from Ember.js!</h1>
<p>The link to the home page is {{#link-to 'application'}}here{{/link-to}}</p>
</div>
</div>
</code></pre>
<p>And the end of part one should be rendered by Ember looking like this:</p>
<p><img src="https://jtescher.github.io/assets/creating-a-metrics-dashboard-with-ember-and-rails-part-one/ember-home-screen.png" alt="Final"></p>
<p>You can now go on to <a href="/creating-a-metrics-dashboard-with-emberjs-bootstrap-and-rails-part-two">part two</a> and start building dynamic<br>
tables!</p>
tag:blog.juliantescher.com,2014:Post/how-to-keep-your-data-consistent-with-foreign-key-constraints2014-03-31T11:28:41-07:002014-03-31T11:28:41-07:00How to keep your data consistent with foreign key constraints<p><img src="https://jtescher.github.io/assets/how-to-keep-your-data-consistent-with-foreign-key-constraints/datacenter.jpg" alt="Datacenter"></p>
<p>We all have that co-worker (and have been that co-worker) who SSHs into a<br>
server and runs SQL statements against live data. On staging servers this<br>
can be a minor issue if things go wrong, but in production it can be disastrous.<br>
At <a href="https://www.getwillcall.com">WillCall</a> we often have to spend time<br>
putting our staging data into different configurations for testing purposes<br>
and have felt the pain of inconsistent data more than once.</p>
<p>Today we’re going to talk about data consistency, why keeping your data<br>
consistent is always a challenge, and what you can do about it.</p>
<p>Integrity issues can creep in unintentionally if you do not have a<br>
deep understanding of how ActiveRecord callbacks and validations work and<br>
which methods skip them entirely!</p>
<p>For example if you have a <code class="prettyprint">Post</code> model and each <code class="prettyprint">Post</code> had many <code class="prettyprint">Comments</code>, when you <br>
call <code class="prettyprint">post.destroy</code> with the <code class="prettyprint">dependent: :destroy</code> option, it will destroy the <br>
associated comments as well.</p>
<pre><code class="prettyprint lang-ruby">class Post < ActiveRecord::Base
has_many :comments, dependent: :destroy
end
class Comment < ActiveRecord::Base
belongs_to :post
end
</code></pre>
<p>This keeps your data consistent. You have no orphaned comments floating around<br>
waiting to explode when you call <code class="prettyprint">comment.post.title</code>.</p>
<p>However if someone were to mistakenly use<br>
post.<a href="http://api.rubyonrails.org/classes/ActiveRecord/Relation.html#method-i-delete">delete</a><br>
instead of post.<a href="http://api.rubyonrails.org/classes/ActiveRecord/Relation.html#method-i-destroy">destroy</a><br>
the callbacks that destroy the associated comments would never be run!</p>
<p>The Rails guides have a list of <br>
<a href="http://guides.rubyonrails.org/active_record_callbacks.html#skipping-callbacks">dangerous methods that skip callbacks</a><br>
for various reasons and should probably be avoided by <del>junior</del> most<br>
developers. They include:</p>
<ul>
<li>decrement</li>
<li>decrement_counter</li>
<li>delete</li>
<li>delete_all</li>
<li>increment</li>
<li>increment_counter</li>
<li>toggle</li>
<li>touch</li>
<li>update_column</li>
<li>update_columns</li>
<li>update_all</li>
<li>update_counters</li>
</ul>
<h3 id="solution-foreign-key-constraints_3">Solution: Foreign key constraints. <a class="head_anchor" href="#solution-foreign-key-constraints_3">#</a>
</h3>
<p>Foreign key constraints are the database’s solution to this data integrity <br>
problem. They are basically a way to tell the database to only allow actual <br>
Post IDs in the comments <code class="prettyprint">post_id</code> column. This means if you tried to add a <br>
comment to a non-existent or deleted post, or delete a post that has comments, <br>
it would raise an <code class="prettyprint">ActiveRecord::InvalidForeignKey</code> exception.</p>
<p>Rails does not have support for foreign key constraints because<br>
<a href="http://en.wikipedia.org/wiki/David_Heinemeier_Hansson">DHH</a> is not a<br>
fan of them, but there are several gems that will add this ability for you. <br>
<a href="https://github.com/matthuhiggins/foreigner">Foreigner</a> is the most popular, <br>
but I have been having good results with the more full featured <br>
<a href="https://github.com/lomba/schema_plus">SchemaPlus</a>. I’ll show how to use <br>
both:</p>
<h3 id="foreigner_3">Foreigner <a class="head_anchor" href="#foreigner_3">#</a>
</h3>
<p>Foreigner is a simple gem that just adds methods to create foreign keys in<br>
mysql, postgres, and sqlite. To install Foreigner, add the following to your<br>
Gemfile:</p>
<pre><code class="prettyprint lang-ruby">gem 'foreigner', '~> 1.6.1'
</code></pre>
<p>And then install with <code class="prettyprint">$ bundle install</code>.</p>
<p>Now you can use the <code class="prettyprint">foreign_key</code> method in your migrations and the foreign<br>
key constraint will be added for you.</p>
<pre><code class="prettyprint lang-ruby">create_table :comments do |t|
t.string :body
t.foreign_key :posts
end
</code></pre>
<p>And that’s it! You can also add <code class="prettyprint">null: false</code> to ensure that the post_id is <br>
not nil.</p>
<h3 id="schemaplus_3">SchemaPlus <a class="head_anchor" href="#schemaplus_3">#</a>
</h3>
<p><a href="https://github.com/lomba/schema_plus">SchemaPlus</a> is another option. <br>
Although being slightly less popular it adds some conveniences that foreigner <br>
does not like <br>
<a href="https://github.com/lomba/schema_plus#column-defaults-expressions">column default expressions</a><br>
which I might talk about in another post. Another benefit is that it will <br>
automatically add foreign key constraints to all <code class="prettyprint">t.references</code> and<br>
<code class="prettyprint">t.belongs_to</code> methods in your migrations for you. To install schema_plus add <br>
the following to your Gemfile:</p>
<pre><code class="prettyprint lang-ruby">gem 'schema_plus', '~> 1.4.1'
</code></pre>
<p>And then install with <code class="prettyprint">$ bundle install</code>. And you’re done! When you start your <br>
next project this is definitely something I would try playing with. There are <br>
also many options you can pass that customize your foreign key constraints <br>
described <a href="https://github.com/lomba/schema_plus#foreign-key-constraints">here</a>.</p>
<h3 id="testing-integrity_3">Testing Integrity <a class="head_anchor" href="#testing-integrity_3">#</a>
</h3>
<p>Finally adding a few tests is always a good thing, so if you want to test that <br>
you cannot accidentally violate your data integrity you could do something <br>
like this in <a href="https://github.com/rspec/rspec">rspec</a>.</p>
<pre><code class="prettyprint lang-ruby">require 'spec_helper'
describe 'Post Integrity' do
it 'should not allow posts to be destroyed if they have comments' do
post = create(:post)
create(:comment, post: post)
expect { post.destroy! }.to raise_error(ActiveRecord::DeleteRestrictionError)
end
it 'should not allow posts to be deleted if they have comments' do
post = create(:post)
create(:comment, post: post)
expect { post.delete }.to raise_error(ActiveRecord::InvalidForeignKey)
end
end
</code></pre>
tag:blog.juliantescher.com,2014:Post/how-to-set-up-a-rails-4-1-app-on-aws-with-elastic-beanstalk-and-postgresql2014-03-25T12:28:18-07:002014-03-25T12:28:18-07:00How to set up a Rails 4.1 app on AWS with Elastic Beanstalk and PostgreSQL<p><img src="https://jtescher.github.io/assets/how-to-set-up-a-rails-4-1-app-on-aws-with-elastic-beanstalk-and-postgresql/aws-logo.png" alt="AWS Elastic Beanstalk"></p>
<p><strong>Update: This post is now a bit outdated. There is a<br>
<a href="http://jtescher.github.io/how-to-set-up-a-rails-4-2-app-on-aws-with-elastic-beanstlk-and-postgresql">NEW VERSION</a><br>
of this post that has updated instructions for the new Elastic Beanstalk and Rails 4.2.</strong></p>
<p>Managing ops on a small team can be a real pain. At <a href="https://www.getwillcall.com/">WillCall</a> our infrastructure is<br>
pretty simple but we still have to spin up and down lots of servers every day to handle the varying traffic across our<br>
services. Three years ago when we had just started the company we were doing this manually with<br>
<a href="http://www.getchef.com/">chef</a>, but it could be error-prone and started to feel like a full-time job.</p>
<p>For simple projects, tools like <a href="https://www.heroku.com/">heroku</a> can be perfect. Great for prototyping apps and testing<br>
out different ideas without a lot of hassle. But when your project gets more complicated and you want to have more<br>
control of your servers, load balancers, workers, auto-scaling conditions, etc, you will feel this pain as well.</p>
<p>There are many services that provide the ability to get a Rails app up and running quickly while still keeping full<br>
control of your infrastructure, and my current favorite is Amazon’s<br>
<a href="http://aws.amazon.com/elasticbeanstalk/">Elastic Beanstalk</a>. The service is aptly described by Amazon as follows:</p>
<blockquote>
<p>AWS Elastic Beanstalk makes it even easier for developers to quickly deploy and manage applications in the AWS cloud.<br>
Developers simply upload their application, and Elastic Beanstalk automatically handles the deployment details of<br>
capacity provisioning, load balancing, auto-scaling, and application health monitoring.</p>
</blockquote>
<p>Now that Amazon <a href="http://aws.amazon.com/rds/postgresql/">supports PostgreSQL via RDS</a> having a fully-managed<br>
postgres-backed Rails app has never been easier!</p>
<p>You can find all of the code for this post at<br>
<a href="https://github.com/jtescher/example-rails-elasticbeanstalk-blog">github.com/jtescher/example-rails-elasticbeanstalk-blog</a></p>
<p>If you get stuck or have other issues the<br>
<a href="http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/Welcome.html">documentation for Elastic Beanstalk</a> is pretty good.</p>
<h2 id="getting-started_2">Getting Started: <a class="head_anchor" href="#getting-started_2">#</a>
</h2>
<p>Sign up for an AWS account via the instructions at<br>
<a href="https://console.aws.amazon.com/elasticbeanstalk/">console.aws.amazon.com/elasticbeanstalk</a> and then download the<br>
Elastic Beanstalk Command Line Tools via Homebrew (or <a href="http://aws.amazon.com/code/6752709412171743">here</a> for PC)</p>
<pre><code class="prettyprint">$ brew update
$ brew install aws-elasticbeanstalk
</code></pre>
<h2 id="create-the-app_2">Create the app: <a class="head_anchor" href="#create-the-app_2">#</a>
</h2>
<p>The most current version of rails at the time of this writing is 4.1.0.rc1 so that’s what we will use now.</p>
<pre><code class="prettyprint">$ gem install rails -v 4.1.0.rc1
$ rails new blog --database=postgresql
$ cd blog
$ git init && git add -A && git commit -m "Initial commit"
</code></pre>
<h2 id="initialize-beanstalk-environment_2">Initialize beanstalk environment <a class="head_anchor" href="#initialize-beanstalk-environment_2">#</a>
</h2>
<pre><code class="prettyprint">$ eb init
</code></pre>
<p>I would choose the following settings, but for a description of each option see the AWS example<br>
<a href="http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/create_deploy_Ruby_rails.html#create_deploy_Ruby_eb_init-rds">here</a></p>
<pre><code class="prettyprint">Enter your AWS Access Key ID (current value is "AKIAIOSEXAMPLE"):
Enter your AWS Secret Access Key (current value is "PfiCYEXAMPLE"):
Select an AWS Elastic Beanstalk service region.
2) US West (Oregon)
Enter an AWS Elastic Beanstalk application name
(auto-generated value is "blog"):
Enter an AWS Elastic Beanstalk environment name
(current value is "blog-env"):
Select an environment tier.
1) WebServer::Standard::1.0
Select a solution stack.
44) 64bit Amazon Linux 2013.09 running Ruby 1.9.3
Select an environment type.
1) LoadBalanced
Create an RDS DB Instance? [y/n]: y
Create an RDS BD Instance from (current value is "[No snapshot]"): 1
Enter an RDS DB master password:
Retype password to confirm:
If you terminate your environment, your RDS DB Instance will be deleted and you will lose your data.
Create snapshot? [y/n]: y
Attach an instance profile (current value is "[Create a default instance profile]"): 1
</code></pre>
<p>Then create an optionsettings file in the newly created .elasticbeanstalk directory called optionsettings.blog-env<br>
(or your custom env name as the extension if you customized it)</p>
<pre><code class="prettyprint"># .elasticbeanstalk/optionsettings.blog-env
[aws:autoscaling:asg]
Custom Availability Zones=
MaxSize=4
MinSize=1
[aws:autoscaling:launchconfiguration]
EC2KeyName=
InstanceType=t1.micro
[aws:autoscaling:updatepolicy:rollingupdate]
RollingUpdateEnabled=false
[aws:ec2:vpc]
ELBScheme=public
ELBSubnets=
Subnets=
VPCId=
[aws:elasticbeanstalk:application]
Application Healthcheck URL=
[aws:elasticbeanstalk:application:environment]
BUNDLE_WITHOUT=test:development
RAILS_SKIP_ASSET_COMPILATION=false
RAILS_SKIP_MIGRATIONS=false
[aws:elasticbeanstalk:hostmanager]
LogPublicationControl=false
[aws:elasticbeanstalk:monitoring]
Automatically Terminate Unhealthy Instances=true
[aws:elasticbeanstalk:sns:topics]
Notification Endpoint=
Notification Protocol=email
[aws:rds:dbinstance]
DBDeletionPolicy=Snapshot
DBEngine=postgres
DBInstanceClass=db.t1.micro
DBSnapshotIdentifier=
DBUser=ebroot
</code></pre>
<p>Then you can test that everything worked with:</p>
<pre><code class="prettyprint">$ eb status
Environment "blog-env" is not running.
</code></pre>
<h2 id="starting-the-app_2">Starting the app <a class="head_anchor" href="#starting-the-app_2">#</a>
</h2>
<p>To start the environment run:<br>
(we will start the app without the rails app first to make sure it’s all set up properly)</p>
<pre><code class="prettyprint">$ eb start
Would you like to deploy the latest Git commit to your environment? [y/n]: n
Waiting for environment "blog-env" to launch.
INFO createEnvironment is starting.
INFO Using elasticbeanstalk-us-west-2-whatever as Amazon S3 s...
INFO Created security group named: sg-aebgroupid
INFO Created load balancer named: awseb-e-m-AWSEBLoa-xloadid ...
INFO Created security group named: sg-cebgroupid
INFO Created Auto Scaling launch configuration named: awseb-e...
INFO Creating RDS database named: apdbnamez. This may take a ...
INFO Created RDS database named: apdbnamez
INFO Waiting for EC2 instances to launch. This may take a few...
INFO Created Auto Scaling group named: awseb-e-dse-stack-AWSE...
INFO Created Auto Scaling group policy named: arn:aws:autosca...
INFO Created Auto Scaling group policy named: arn:aws:autosca...
INFO Created CloudWatch alarm named: awseb-e-dv-stack-AWSEBCl...
INFO Created CloudWatch alarm named: awseb-e-dv-stack-AWSEBCl...
</code></pre>
<p>The environment should now be running. To see the status and url:</p>
<pre><code class="prettyprint">$ eb status --verbose
Retrieving status of environment "blog-env".
URL : blog-env-hkdpsewdfsd.elasticbeanstalk.com
Status : Ready
Health : Green
Environment Name: blog-env
Environment ID : e-jlksjdf8d8s
Environment Tier: WebServer::Standard::1.0
Solution Stack : 64bit Amazon Linux 2013.09 running Ruby 1.9.3
Version Label : Sample Application
Date Created : 2014-01-20 18:45:40
Date Updated : 2014-01-20 19:03:13
Description :
RDS Database: AWSEBRDSDatabase | sdfjlsdkflsk.sdfkjlsdkjf.us...
Database Engine: postgres 9.3.1
Allocated Storage: 10
Instance Class: db.t1.micro
Multi AZ: False
Master Username: ebroot
Creation Time: 2014-01-20 18:53:06
DB Instance Status: available
</code></pre>
<p>If you open the URL that is returned by this command ( should be URL: your-app-env.elasticbeanstalk.com ) you should<br>
see the Elastic Beanstalk welcome page:</p>
<p><img src="https://jtescher.github.io/assets/how-to-set-up-a-rails-4-1-app-on-aws-with-elastic-beanstalk-and-postgresql/welcome.png" alt="Elastic Beanstalk Welcome Page"></p>
<h2 id="getting-the-pg-gem-to-work-on-elasticbeanstal_2">Getting the pg gem to work on elasticbeanstalk <a class="head_anchor" href="#getting-the-pg-gem-to-work-on-elasticbeanstal_2">#</a>
</h2>
<p>The <code class="prettyprint">postgresql-devel</code> yum package is required to install the pg gem on amazon linux and configuring packages on<br>
Elastic Beanstalk instances is as simple as dropping a YAML formatted .config file in a top level .ebextensions folder.</p>
<pre><code class="prettyprint"># .ebextensions/packages.config
packages:
yum:
postgresql-devel: []
</code></pre>
<h2 id="configuring-databaseyml-to-work-with-rds-post_2">Configuring database.yml to work with RDS postgres <a class="head_anchor" href="#configuring-databaseyml-to-work-with-rds-post_2">#</a>
</h2>
<p>Database credentials should never be hard coded and Elastic Beanstalk makes managing environment variables quite simple.<br>
RDS variables are configured and updated automatically so your production section of database.yml can be updated to be<br>
the following:</p>
<pre><code class="prettyprint">production:
<<: *default
database: <%= ENV['RDS_DB_NAME'] %>
username: <%= ENV['RDS_USERNAME'] %>
password: <%= ENV['RDS_PASSWORD'] %>
host: <%= ENV['RDS_HOSTNAME'] %>
port: <%= ENV['RDS_PORT'] %>
</code></pre>
<h2 id="configuring-secretsyml_2">Configuring secrets.yml <a class="head_anchor" href="#configuring-secretsyml_2">#</a>
</h2>
<p>By default Rails now includes a secrets.yml file and your production keys and settings should be set there as<br>
environment variables. The default environment only requires a SECRET_KEY_BASE variable to be defined, so let’s<br>
add that to your environment. First run:</p>
<pre><code class="prettyprint">$ bundle exec rake secret
5387fca6a0a69d945bb57e8be5bce3a119292216dfc95b270275c518641aa3e8db14a5ead261b1d50332a92ed860c544ef24356100ccb391507b1c5b8d46f39b
</code></pre>
<p>Then go to <a href="https://console.aws.amazon.com/elasticbeanstalk/home">console.aws.amazon.com/elasticbeanstalk/home</a> and in<br>
blog-env on the left under configuration click on the cog next to ‘Software Configuration’. At the bottom, enter<br>
SECRET_KEY_BASE on the left and the output of <code class="prettyprint">rake secret</code> on the right.</p>
<p>After you save, it should look like this:</p>
<p><img src="https://jtescher.github.io/assets/how-to-set-up-a-rails-4-1-app-on-aws-with-elastic-beanstalk-and-postgresql/env-var-config.png" alt="Elastic Beanstalk Environment Variable Config"></p>
<h2 id="adding-some-scaffolding_2">Adding some scaffolding <a class="head_anchor" href="#adding-some-scaffolding_2">#</a>
</h2>
<p>To finish up let’s add a post resource so we can start blogging:</p>
<pre><code class="prettyprint">$ rails generate scaffold post title:string body:text
$ bundle exec rake db:migrate
</code></pre>
<h2 id="deploying-the-app-to-aws_2">Deploying the app to AWS <a class="head_anchor" href="#deploying-the-app-to-aws_2">#</a>
</h2>
<p>Commit all the changes we just made:</p>
<pre><code class="prettyprint">$ git add -A && git commit -am "Add post resource, configure database.yml for production"
</code></pre>
<p>Then deploy with:</p>
<pre><code class="prettyprint">$ git aws.push
</code></pre>
<p>If you visit <a href="https://console.aws.amazon.com/elasticbeanstalk/home">https://console.aws.amazon.com/elasticbeanstalk/home</a><br>
you should see the progress of your app as it deploys.</p>
<p>Once that finishes you have your functional app running Rails and postgres! Go to your-app-env.elasticbeanstalk.com/posts<br>
and you’re done!:</p>
<p><img src="https://jtescher.github.io/assets/how-to-set-up-a-rails-4-1-app-on-aws-with-elastic-beanstalk-and-postgresql/posts-index.png" alt="Done: List of posts"></p>