Starting a “professional” Rails 3.1 app with Web App Theme, Devise, and Kaminari

Update: This tutorial is way out of date. If you want to create a modern (ie. 2015) app, please use a generator like RailsBricks.

With the recent release of web-app-theme providing Rails 3.1 support, it’s time once again for me to write a tutorial on how to earn money from cheap clients who can’t afford designers.

For reference, the previous tutorial can be read here.

crud screen

Every Rails developer knows how to create a Rails app. It’s easy as

rails new APP-NAME-HERE

But how many know how to create an app from scratch that looks good enough to sell to clients i.e. with slick design, authentication, authorization, and all that? Sure, there are tutorials out there that cover those components, but most of them cover them only in isolation from each other. A quick tutorial containing multiple components at a time would be a valuable resource to anyone planning to start a new app.

As the resident dilettante in these parts, I’ve decided to create such a tutorial based on a recent demo I made for a prospective client.

This post will discuss how to create a Rails 3.1 application that looks good enough to sell to clients (of course, YMMV) while still having components found in “professional” apps. This tutorial will cover the following:

  • Andrea Franz’s web-app-theme gem – this gem generates themes for your web app (hence the name). The demo and the list of available themes can be found on this page.
  • Devise – our authentication module. Authlogic‘s fine, but I find Devise’s approach less obtrusive.
  • Haml – replaces Erb. Not perfect (e.g. screws up with inline a tags) but the drastic decrease in code makes passing it up difficult.
  • Rspec – replaces Test::Unit. Only setup will be covered in this post, actual usage is left to the reader.
  • Kaminari – gem for pagination. We’re going to use it in place of the previous gem will_paginate

Rest of the tutorial is below the cut.

Continue reading “Starting a “professional” Rails 3.1 app with Web App Theme, Devise, and Kaminari”

Free Rails 3.0 tutorial/manual

Computer Science teachers have it easy. Every time a new semester rolls in, they can simply reuse the material they’ve been using for years.

As a teacher of a quickly evolving web framework, I do not have that luxury.

As I write this, less than 24 hours have passed since the Rails Core team released the new version of Ruby on Rails: version 3.1.0. This means that I now have to update my student manual (i.e. this document) for upcoming classes to use this new version. Having done that before when we moved from Rails 2.3. to Rails 3.0, I know how much of this document will be changed: sections will be gutted, swaths of code rewritten, and at least one new chapter would be added.

And, yet again, I will not be paid a single cent for those updates.

So instead of just letting this nearly obsolete document go to waste, I’ve decided to give it away for free.

Get it here.

Basic Lessons from Ruby Rumble Practice

yay, I won

Normally, I would’ve posted something like this a lot earlier. But work interfered so…

Anyway, since I won the event, I really don’t have an excuse not to do a post. Blow the cut are some of the lessons I (re)learned at the event.

Continue reading “Basic Lessons from Ruby Rumble Practice”

Collections, method chains and train wrecks (and SQL)

Last Friday, I got to teach about collections and closures in Ruby for ECC. That gave me an idea to write a post about one of the mistakes people coming from other languages tend to make when going into Ruby.

Let’s take the first problem from Project Euler:

If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.

Find the sum of all the multiples of 3 or 5 below 1000.

Looks simple enough. In pseudocode, your typical fresh grad programmer might do this:

sum <- 0
for i <- 1 to 999
  if i % 3 == 0 or i % 5 == 0
    sum += i
  end if
end for

A rubyist, however, will compress that 6 line program into a single line. Here is one possible solution:

(1..999).select { |x| x % 3 == 0 or x % 5 == 0 }.reduce(:+)

This line of code chains the 3 main components of the algorithm above:

  1. (1..999) - find a way to process numbers from 1 to 999. Here we created a Range that we can process as a whole.
  2. .select { |x| x % 3 == 0 or x % 5 == 0 } - process only the multiples of 3 and 5. Here, the method called selects only the elements that return true inside the passed block.
  3. .reduce(:+) - find the sum of the elements. Here we used the shorthand form of Ruby's reduce operation that sums the elements.

Let's try a harder example, problem 6:

(1..100).reduce(:+) ** 2 - (1..100).map { |x| x * x }.reduce(:+)

Here we see Ruby's map, which simply creates a copy of the source collection and applying the mapping function to each element. The map above is pretty trivial; we could even replace it with the long form of the reduce method.

(1..100).reduce(:+) ** 2 - (1..100).reduce(0) { |sum, x| sum + x * x }

While method chaining wouldn't be new to the novice developer, the concept of passing functions to methods, allowing greater flexibility, will be. Functional programming has been long forgotten even at the top universities in this country.

Another problem is that method chains can be too long. Some people call these chains "train wrecks". Obviously, this is a subjective matter, but one cannot deny that very long method chains are hard to debug. For example, here's one possible solution to problem 20:

(2..100).reduce(:*).to_s.scan(/./).map { |x| x.to_i }.reduce(:+)

This line simply:

  1. creates a range from 2 to 100 (1 is ignored in the factorial)
  2. calculate the factorial by multiplying them together
  3. convert it to a string
  4. create an array whose elements consist of single characters from the string (split("") also works)
  5. convert each element to integer
  6. calculates the sum of the elements

One way of debugging this long method chain would be to insert a tap method call to inspect the intermediate value of the chain. For example, if you do this:

(2..100).reduce(:*).to_s.scan(/./).map { |x| x.to_i }
.tap { |x| puts x.inspect }.reduce(:+)

you'll get the array of numbers before the reduce.

irb(main):001:0>(2..100).reduce(:*).to_s.scan(/./).map { |x| x.to_i }
.tap { |x| puts x.inspect }.reduce(:+)
[9, 3, 3, 2, 6, 2, 1, 5, 4, 4, 3, 9, 4, 4, 1, 5, 2, 6, 8, 1, 6, 9, 9, 2, 3, 8, 8 
, 5, 6, 2, 6, 6, 7, 0, 0, 4, 9, 0, 7, 1, 5, 9, 6, 8, 2, 6, 4, 3, 8, 1, 6, 2, 1,
4, 6, 8, 5, 9, 2, 9, 6, 3, 8, 9, 5, 2, 1, 7, 5, 9, 9, 9, 9, 3, 2, 2, 9, 9, 1, 5,
 6, 0, 8, 9, 4, 1, 4, 6, 3, 9, 7, 6, 1, 5, 6, 5, 1, 8, 2, 8, 6, 2, 5, 3, 6, 9, 7
, 9, 2, 0, 8, 2, 7, 2, 2, 3, 7, 5, 8, 2, 5, 1, 1, 8, 5, 2, 1, 0, 9, 1, 6, 8, 6,
4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
=> 648

Not exactly pretty, nor is it the most interesting use of tap, but it still gets the work done.

As a bonus, I'd just like to share a realization I had a while back.

Web developers shouldn't have to have problems with list processing because they deal with lists all the time: in SQL!

Think about it, you can define filter options in WHERE clauses, while map and reduce can be done in the SELECT clause. Assuming you have a table numbers with a column number with 100 records, each corresponding to numbers from 1 to 100, problem 6 can be solved by the following SQL statement:

SELECT SUM(number) * SUM(number) - SUM(number * number) FROM numbers

Select Best Download Server for Ubuntu Packages

I just learned recently that there are no local download servers for Ubuntu packages here in the Philippines. In other words, for the past few months (or years), every apt-get install I do downloads the packages from the main Canonical server in UK.

And I thought my slow download speeds were just caused by this country’s crappy internet.

Anyway, the solution is simple. In Synaptic Package Manager, go to Settings -> Repositories and choose Other… from the “Download from” dropdown. This will open the Choose a Download Server window. Just click the Select Best Server and Ubuntu will ping all download servers, choosing the best server automatically.

select best server

This will probably select a Singaporean or Malaysian server depending on your connection.