Wednesday, 30 November 2011

Rails3.1- Asset isn't precompiled error

Recently on a production env, I was annoyed with "<Asset> isn't precompiled" error, though it was compiled using rake assets:precompile. I wasn't able to figure out the root cause. However I was able to work around.

I'd assets included on the view, using <content_for>. I removed and required it within the controller specific asset file and things started working. So as far as I can say NEVER require assets within the view, using <content_for> or <provide>. Asset pipeline, chokes for some reason.

Tuesday, 29 November 2011

HTML5 File Api- Preview during image upload

File Api is one of the coolest addition with HTML5, though not all major browsers has started supported this(as of this writing). It allows the client to handle basic file validations and image preview before sending it to the server. Here's how I did:


<input type="file" name="photo" accept="image/*"  />
<div class="preview"></div>


var MAX_FILE_SIZE = 5242880; // 5MB
var ACCEPT_FILE_TYPE = /image\/(jpg|jpeg|png)/i;

function handleFileSelect(evt) {
  var files =; // FileList object
  var form = $('form');

  // Loop through the FileList and render image files as thumbnails.
  for (var i = 0, f; f = files[i]; i++) {
    // Only process image files.
    if (!f.type.match(ACCEPT_FILE_TYPE)) {
      showFormError('File is not an image', form);

    if (parseInt(f.size) > MAX_FILE_SIZE) {
      showFormError('File size exceeds 5MB.', form);

    var reader = new FileReader();
    // Closure to capture the file information.
    reader.onload = (function(theFile) {
      return function(e) {
        // Render thumbnail.
        var img = ['<img src="',,
                          '" title="',, '"/>'].join('');

    // Read in the image file as a data URL.

function showFormError(msg, form) {
  var errorDiv = document.createElement('div');
  errorDiv.className = 'errors';
  errorDiv.innerHTML = msg;


That's it... 

Thursday, 24 November 2011

Paperclip: Image or Photos from url

In general, Paperclip accepts file uploaded from local machine. However we can extend it to support image from url (Ex., Saving user avatars from twitter or facebook)


  has_attached_file :avatar, ....
  attr_accessor :avatar_url
  def avatar_url=(img_url)
    io = open(URI.parse(img_url))
    # define original_filename meth on io, dynamically
    def io.original_filename; base_uri.path.split('/').last; end
    self.avatar = (io.original_filename.blank? ? nil : io)
  rescue Exception => ex
    puts ex.message "Error while parsing avatar: #{ex.message}"
    @avatar_url = img_url

Glitch :, returns an StringIO object, which might not be as efficient as a Tempfile. So considering adding this patch.


require 'open-uri'

# make OpenURI to use tempfiles instead of io.
# Patched from
OpenURI::Buffer.module_eval do
  remove_const :StringMax
  const_set :StringMax, 0

We are ready now..

Ex Usage :  u = => '')

Good luck :)

Wednesday, 23 November 2011

Rails: ffmpeg video generation from images

To generate video from a series of images/photos in rails, I use this code snippet:

    # generate the video and store it under the appropriate public path.
    def create_video_from(foto_paths = [], tyype)
      status ='ffmpeg', ffmpeg_options)
      remove_tmp_links(foto_paths.length)'/tmp/output.mp4', Rails.root.to_s + "/public/#{tyype.to_s}_video.mp4")

    def ffmpeg_options
      "-r 1 -f image2 -i '/tmp/img%03d.jpg' /tmp/output.mp4"

    # ffmpeg requires filenames matching a pattern, so create them under /tmp
    def create_tmp_links(foto_paths = [])
      foto_paths.each_with_index do |path, i|
        tmp_path = "/tmp/img%03d.jpg" % (i + 1)
        File.symlink(path, tmp_path)

    # remove those symlinks
    def remove_tmp_links(fotos_cnt = 0)
      fotos_cnt.times do |i|
        tmp_path = "/tmp/img%03d.jpg" % (i + 1)

Hope it helps!

Tuesday, 22 November 2011

Rails: Aspect fit images

Aspect fitting images with a frame has always been a common requirement across websites that supports image browsing. Here's how I would like to do it in Rails web applications:


  def aspect_fit(frame_width, frame_height)
    image_width, image_height = self.data_dimension.split('x')
    ratio_frame = frame_width / frame_height
    ratio_image = image_width.to_f / image_height.to_f
    if ratio_image > ratio_frame
      image_width  = frame_width
      image_height = frame_width / ratio_image
    elsif image_height.to_i > frame_height
      image_width = frame_height * ratio_image
      image_height = frame_height
    "width:#{image_width.to_i}px; height:#{image_height.to_i}px;"
Note: self.data_dimension, will return a string of "widthxheight" for a photo. I store it when uploading images. You might also use, Paperclip::Geometry.from_file to get the dimension during run-time.

In Views:

<div class='photo'>
  <img src='<%= @photo.url %>' style='<%= @photo.aspect_fit(500, 500) %>'/>


#photo { position: relative; height: 500px; width: 500px; background-color: black; }
#photo img { position: absolute; bottom: 0; left: 0; right: 0; top: 0; margin: auto; }

That should be it.

Rails: Simple File upload

Inspired from Paperclip, I always wanted to have a simple file upload solution in Rails, which doesn't require any thumbnail generation. Here it's:


  attr_accessor :data
  FOTO_DIR = File.join(Rails.root, 'public/photos')
  FOTO_PATH = File.join(FOTO_DIR, ':id/:filename')
  ALLOWED_TYPES = ['image/jpg', 'image/jpeg', 'image/png']

  validates :data_filename, :presence => true
  validates :data_size, :inclusion => { :in => 0..(5.megabytes) }, :allow_blank => true
  validates :data_content_type, :inclusion => { :in => ALLOWED_TYPES }, :allow_blank => true

  after_save :save_data_to_file

  def data=(file)
    return nil if file.blank?
    @data = file.path # temp file path
    self.data_filename = file.original_filename.to_s
    self.data_content_type = file.content_type.to_s
    self.data_size = file.size.to_i
    self.data_dimension = get_geometry(file)

  def path
    fpath = FOTO_PATH.dup
    fpath.sub!(/:filename/, self.data_filename)

  def url
    path.sub("#{Rails.root}/public", "")


  def save_data_to_file
    return true if
    ensure_dir(File.join(FOTO_DIR, "Saving file: #{self.path}"
    FileUtils.cp(, self.path)

  def ensure_dir(dirname = nil)
    raise "directory path cannot be empty" if dirname.nil?
    unless File.exist?(dirname)

  def get_geometry(file)
    `identify -format %wx%h #{file.path}`.strip
Issuing Photo.create(:data => params[:photo]) should create the file in filesystem and save the record in DB, where params[:photo] is the file field value.

Its quite easy to make slight changes to this code piece to make it fit for your requirement , rather than writing patches/hacks to any gem.

Monday, 21 November 2011

Rails: Basic vim config

Vim supports a whole lot of features, however I've listed the basic config to get started with development in rails.

set nocompatible          " We're running Vim, not Vi!
syntax on                 " Enable syntax highlighting
filetype plugin indent on " Enable filetype-specific indenting and plugins

" Load matchit (% to bounce from do to end, etc.)
runtime! macros/matchit.vim

augroup myfiletypes
  " Clear old autocmds in group
  " autoindent with two spaces, always expand tabs
  autocmd FileType ruby,eruby,yaml set ai sw=2 sts=2 et
augroup END

nmap <leader>rci :%!ruby-code-indenter<cr>
Apart from this, you can also tweek any config under /etc/vim/vimrc , based on your preference.

Friday, 18 November 2011

Rails3.1 - Manage CSS/JS with Asset Pipeline

An Ideal way to mange your css/js using sprockets in rails (>~ 3) apps. Asset pipeline is enabled by default from rails 3.1 and it uses 'app/assets' to maintain the asset files. We can also have 'lib/assets' and 'vendor/assets' to host the assets.

These assets are included in the layout using

<%= stylesheet_link_tag    "application" %>
<%= javascript_include_tag "application" %>
and the app/assets/stylesheets/application.css will

  *= require_self
  *= require_tree .
Ideally, we wouldn't want to require the whole tree for stylesheets or javascripts. We only need application and the controller specific assets to be loaded on any given page and so I recommended having the following setup.

Typical application.css
*= require reset-min
*= require_self

In layout:

  <%= stylesheet_link_tag    "application", params[:controller] %>
  <%= javascript_include_tag "application", params[:controller] %>
  <%= yield(:head) %>
Hereby, we load only the common styles/scripts applicable for the app, from application and controller specific styles. yield(:head) is to require custom styles/scripts for a page.

Also, assets from vendor/assets or lib/assets can be required within application or controller specific files.

Note: with this approach, the custom files has to be added manually to the precompile list, for them to be precompiled. config.assets.precompile += %w( *.js *.css ) - should do the trick.

Tuesday, 15 November 2011

Setup rhodes environment on Ubuntu

Recently I was setting up rhodes on my ubuntu machine to mobile app development, where I'd to go through multiple references. So I decided to make a write up to serve as one reference for all.

Assumption - You have ruby and rubygems installed.

sudo apt-get install sun-java6-jdk
gem install rhodes

Download android sdk from
untar the downloaded package ( android-sdk-linux)
mv android-sdk-linux /usr/local
cd /usr/local/android-sdk-linux/tools

Download android ndk from
untar the downloaded package ( Ex., android-ndk-r7 )
mv android-ndk-r7 /usr/local

Run 'rhodes-setup' and specify JDK, android sdk and ndk paths.
For our case it will look like
JDK path - /usr/lib/jvm/java-6-sun
Android SDK path - /usr/local/android-sdk-linux
NDK path - /usr/local/android-ndk-r7

Generate the application:
rhodes app test_app http://localhost:3000/application
OR create an application in the cloud using (preferred option)

Now 'rake run:android' and have fun :)

Saturday, 12 November 2011

Grub 2 - Limit kernel entries

With Grub2 menu.lst has been removed and there's no way to change "#howmany" to limit the number of kernel entries to be displayed on the boot menu. So here's how we do it:

Find this section in /etc/grub.d/10_linux . Note this is not the entire file!. Added sections are in bold dark red:


# Added to limit number of Linux kernels displayed.

while [ "x$list" != "x" ] ; do
linux=`version_find_latest $list`
echo "Found linux image: $linux" >&2
..... < omitted lines >
..... < several lines from the bottom of the file >

list=`echo $list | tr ' ' '\n' | grep -vx $linux | tr '\n' ' '`

# Added to limit number of Linux kernels displayed.

 Save the file and run 'update-grub'.

Friday, 11 November 2011

New Rails 3.1 app

Generate new rails 3.1 app(with mysql db) with the following command:

rails new testapp -d mysql --skip-bundle

--skip-bundle will not run 'bundle install' during app creation.

Thursday, 10 November 2011

Truncate file linux

Simple bash script to truncate a huge log, may be log files

cat /dev/null > /var/log/production.log

Mysql - Enable slow query logging

Enabling slow query logs is one of the recommended options to determine long running queries, lock timeout issues and non-indexed queries.

Uncomment the below lines in ~/.my.cnf or /etc/my.cnf under #Logging

#log-output                     = FILE
#slow-query-log                 = 1
#slow-query-log-file            = /var/lib/mysqllogs/slow-log
#long-query-time                = 2
#log-queries-not-using-indexes  = 1

and restart the server.

Use mysqldumpslow to quickly parse through huge log files, as below.

mysqldumpslow /var/lib/mysqllogs/slow-log

Script to convert all tables to InnoDB

Here is a quick shell script to convert all tables in a database to InnoDB. No dependancies other than a command line prompt on a Unix like system and the standard MySQL tools:

for T in `mysql -u root -B -N -e “show tables” test`; do mysql -u root -e “alter table $T type=innodb” test; done

Replace “test” with the target database. This pattern is also great for optimizing or analyzing your MyISAM tables.

Wednesday, 9 November 2011

Paperclip fog storage : content_type fix

Add this initializer to set the correct content_type when you use fog storage with paperclip - version <= '2.3.12'

# patch from
module Paperclip
  module Storage
    module Fog

      def flush_writes
        for style, file in @queued_for_write do
          log("saving #{path(style)}")
            :body         => file,
            :key          => path(style),
            :public       => @fog_public,
            :content_type => file.content_type.to_s.strip
        @queued_for_write = {}


Tuesday, 8 November 2011

mysql gem dependencies in Ubuntu

Very Often when we setup a Rails application on a fresh Ubuntu machine, we end up facing error when installing mysql gem, when executing bundle install.

Make sure you have mysql gem dependencies installed, (and offcourse the actual mysql server as well)

sudo apt-get install libmysql-ruby libmysqlclient-dev