Fruitr is on Rails 4

22 September, 2014

I have a side project that I am very passionate about.
It lives at fruitr.rishighan.com

It was originally developed on an older version of Rails. Since I revamped this site on Rails 4, I felt I should do the same for the project that deserves to be shown to the world.

It was relatively easy to upgrade it to Rails 4. Aside from the usual broken gem dependencies, there was nothing strange or extraordinary stopping the upgrade. I did have the Echonest API impose a rate limit on me; and the none of my API requests returned any response. This baffled me for a whole 15 minutes till I figured out that there is an option for developers to 'upgrade' their account. It is free, provided you tell them what your app does and they will remove that ridiculous rate limit.

As soon as I told Echonest that my app is not doing anything to threaten their existence, they upgraded my rate-limit and the app started working. I thought of writing a quick how-to on deploying the rails app using Capistrano.

I use the excellent hosting service provided by Linode. It runs an instance of Ubuntu 14.04. Now, on to the good stuff. Bear in mind, this assumes that you have already set up your server environment with rvm, passenger and the appropriate directives in nginx.conf

1
2
3
4
gem 'capistrano'
gem 'capistrano-recipes'
gem 'capistrano-rvm'
gem 'capistrano-bundler' 

Then install your capistrano files.

1
cap install

This generates the following:

1
2
3
4
5
6
mkdir -p config/deploy
create config/deploy.rb
create config/deploy/staging.rb
create config/deploy/production.rb
mkdir -p lib/capistrano/tasks
Capified

Past this, ssh into the server and create the app directory. In this case, mkdir fruitr and set the appropriate ownership and permissions chown -R rishi:rishi fruitr and chmod -R 755 fruitr

Once this is done, modify your Capfile, production.rb and deploy.rb
In your Capfile, set the required gems. I needed

1
2
3
require 'capistrano/rvm'
require 'capistrano/deploy'
require 'capistrano/bundler'

My production.rb defines the hostname and the roles.

1
2
3
4
5
set :stage, :production
server 'rishighan.com', user: 'rishi', roles: %w{web app}

#RVM stuff
set :rvm_type, :user

Finally, my deploy.rb looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# config valid only for Capistrano 3.1
lock '3.2.1'

set :application, 'fruitr'
set :repo_url, 'git@github.com:rishighan/fruitr.git'

# Default branch is :master
# ask :branch, proc { `git rev-parse --abbrev-ref HEAD`.chomp }.call

# Default deploy_to directory is /var/www/my_app
set :deploy_to, '/home/rishi/fruitr'

# Default value for :scm is :git
set :scm, :git

This configuration is specific for my project. However, you can use this if you have Linode as your host and are using git as your SCM.

Using scopes in Rails 4

09 August, 2014

I was introduced to scopes in Rails through my need to chain queries to get the result I needed. This site's hero navigation filters post titles from different categories. I need to display projects on the right and all other categories on the left.

The only category common to both is hero
Scopes in Rails are basically a way to define methods on a model, in such a way that you can retrieve data and information on a subset of a database.

Example:
This snippet defines two scopes on the Post model: hero and projects
Note that the scope uses associations I have set up between Post and Category

1
2
3
#scope that isolates "heroes" and "projects"
scope :hero, -> {Post.includes(:categories).where('categories.title = (?)', "Hero")}
scope :projects, -> {Post.includes(:categories).where('categories.title = (?)', "Projects")}

This will help me do the following:

1
2
Post.hero #basically returns all posts filed under "Hero" catgegory
Post.projects #Returns all posts under "Projects"

This also helps me do some advanced stuff such as chaining queries. I have a method that helps me filter drafts. Then, I merge the two queries to get only non-draft posts that fall under Projects and Hero

1
2
3
4
5
6
7
8
#checks for the is_draft flag
def self.is_draft(what)
   post = Post.where('is_draft = (?)', what )
end

#controller
#this is how you merge the two scopes and then get the desired result
@projects = Post.is_draft("no").projects & Post.hero

Scopes are a great way of working with subsets of your database that you work with frequently. To put it in context, I am often going to need to work with Project posts and I want the convenience of calling a method on the model, which feels natural.

The redemption of a certain Misal Pav

07 August, 2014

There are things that matter and there are things that can afford to slide.

Misal Pav is the former.

It is something that infuses life into the most derelict of tendencies. It is the fire that breathes life into fires. It is the product of a culture that was built on foundations of tumeric and red chili powder, with liberal amounts of salt to taste. Don't allow yourself to be fooled by the economy of ingredients. It is effective because of this economy, not in spite of it.

Misal Pav has transcended the boundaries of generations, lending itself to whoever creates it and puts their own mark on it, causing its name to prosper and flourish despite the apparent bastardization. There is only one true Misal Pav; that comes from wherever its creator says it came from.

This is the poor cousin of the poorest cousins of whatever snack/breakfast/lunch counterpart you can name from your country of origin. It's beauty lies in the simplicity of the ingredients that go into its making as well as the aftermath of its consumption. Fire all the way, they say.

Fire. All the way.