Freitag, 28. Dezember 2012

Save time per Rails controller query

Ruby On Rails is sooo elaborated. It ships with a lot of optimizations included, like query caching, page caching and so forth. But this is about optimizing a continuous polled controller. Let's assume getting the current state of some machines. Therefore I use a simple cyclic remote link as I described in an earlier post or in CoffeeScript. It queries the controller once per 10 seconds.
The database migrations:
class CreateMachines < ActiveRecord::Migration
  def change
    create_table :machines do |t|
      t.string :name
      t.integer :state_id
      t.timestamps
    end
  end
end
class CreateStates < ActiveRecord::Migration
  def change
    create_table :states do |t|
      t.string :name
    end
  end
end
The models/machine.rb:
class Machine < ActiveRecord::Base
  belongs_to :state
  validates_presence_of :state_id
end
And the models/state.rb:
class State < ActiveRecord::Base
  has_many :machines
end
The controllers/machines_controller.rb:
class MachinesController < ApplicationController
  def index
    respond_to do |format|
      format.html {
        @machines = Machine.includes(:state).order("machines.name ASC")
      }
      format.js {
        @machines = Machine.where("machines.updated_at >= :updated_at",
            { :updated_at => session[:last_status_request] }).includes(:state)
      }
    end
    session[:last_status_request] = Time.now
  end
end
If a simple GET request was received by the MachinesController, it returns all machines including their state and sets the request timestamp in the session initially. They are displayed in the views/machines/index.html.erb:
<ul>
  <% machines.each do |machine| %>
    <li>
      <%= machine.name %>: <span id="<%= dom_id(machine) %>_state"><%= machine.state.name %></span>
    </li>
  <% end %>
</ul>
<%= link_to 'Refresh', machines_path, :remote => true, :class => 'auto_remote' %>
The XMLHTTPRequest triggered by the remote link reaches the format.js part of the MachinesController. Please notice that only those machines are queried, who have been updated since the last status request timestamp. So a lot less machines and their state are queried, instantiated and sent back to the client.
The result is processed in the index.js.erb:
<% @machines.each do |machine| %>
  state = $('#<%= dom_id(machine) %>_state');
  state.text("<%= machine.state.name %>");
<% end %>
This post was more about the conception how to save processing time than an optimized-to-the-bones tutorial. For example you better should render a 304 Not Modified, if no state was updated since the last polling request.
Supported by Ruby on Rails 3.2.8

Dienstag, 25. Dezember 2012

The AOP in Ruby

Needless to say Ruby stands for readable codes, prototyping mixins and other paradigms. In this post I present the paradigma of aspect oriented programming in Ruby (short AOP). What is it good for?
Say you included a cool gem, but it contains one feature, you have to enhance to fulfill your requirement. You have got two options:
  1. copy the code of the feature and overwrite the method with the enriched logic
  2. AOP
The drawback with the first option is the copy & overwrite part. Overwriting means your application will never benefit from bugfixes and enhancements of the original code.
That's why you better go with the aspect oriented paradigma, recycling the original code and injecting new logic.
Fortunately Ruby as a great metaprogramming language offers an easy exposure to AOP. Easy as follows.
module ActsAsExample
  def feature
    @feature ||= "The original"
    @feature + " feature is oh-some."
  end
end
The ActsAsExample module contains the feature method. Including it into the Example class:
class Example
  include ActsAsExample
end
Using the included feature:
Example.new.feature
returns The original feature is oh-some., as expected. Let's add a new aspect to the Example class:
class Example
  include ActsAsExample
  alias_method :original_feature, :feature

  def feature
    @feature = "My new cool fancy"
    original_feature
  end
end
The use of the same feature method:
Example.new.feature
now returns My new cool fancy feature is oh-some.. The feature method behaves different compared to the original code though the original code was used.
A bugfix of the ActsAsExample module to:
module ActsAsExample
  def feature
    @feature ||= "The original"
    " feature is awesome."
  end
end
will break through to the Example class and again calling the feature:
Example.new.feature
returns the bugfixed My new cool fancy feature is awesome. and please note that no change was made in the copy method of the Example class.
Clean!
Maybe my example is not the best, but I hope it illustrates how easy AOP in Ruby is.
Additionally I point to the Ruby Aquarium framework.
Supported by Ruby 1.9.3

Donnerstag, 20. Dezember 2012

VI: best Ruby IDE since 1976

First I have to admit that you caught me in a lie.
The very best editor for developing software is not the VI but its conduction, the great VIM (Vi IMproved). It's not "cool" like TextMate and Apple hipsters might give a sniff at VIM, but it's available on every professional OS (Windows is none!)
From time to time you also have to debug some logic on a remote server, possibly even on a production server. Then your best choice is tunneling via SSH and debugging in your terminal by using VIM.
The mentioned method of operation is not only for Rubyists. It's the way to go for everyone working on remote machines. Even those Java island guys have to turn their back on NetBeans/ IntelliJ/ Eclipse in some situations.
Other good points are VIM's portable configuration, the high level of customizability and extensibility and not to forget its powerful and skilled community.
Well, none says VIM is intuitive. There is a learning curve when you first start using it, and it does require a bit of a commitment. But you will be rewarded for the rest of your coding life time.
If VIM is not already installed on your Debian based system (like Ubuntu), just do:
user$ sudo apt-get install vim vim-common
or in Fedora:
user$ sudo yum install vim-common vim-enhanced vim-minimal
As a next step maybe you will want to edit your vimrc:
user$ vi ~/.vimrc
There you can configure a lot and it will be part of your VIM life style. It could look like this:
set nocompatible " make VIM useable by switching off the compatibility to grandpa VI
 
set diffexpr=MyDiff() " overwrite the default diff function of VIM
function MyDiff()
  let opt = ''
  if &diffopt =~ 'icase' | let opt = opt . '-i ' | endif
  if &diffopt =~ 'iwhite' | let opt = opt . '-b ' | endif
  silent execute '!C:\Vim\vim61\diff -a ' . opt . v:fname_in . ' ' . v:fname_new . ' > ' . v:fname_out
endfunction
 
set history=500 " keep 500 lines of command line history
set tabstop=4 " set the tab Stops to 4 white spaces
set shiftwidth=4 " set the indention to 4 white spaces. along with tabstop=4 it implies an indention with 1 tab
set noexpandtab " do not replace Tabs with white space while editing
 
set nobackup " do not write Backup Files while saving

set showmatch " jump to the opening bracket briefly, if a closing bracket is typed

set cindent " cindent is a quite intelligent indention

set fo=croq " continues the comments in the next line

set foldmethod=marker " tagged lines with {{{ and }}} can be hidden with zc or opened with zo
set mousehide " hides mouse pointer while typing

set background=dark " set the background dark

syntax on " enable syntax highlightening
filetype on
filetype indent on
filetype plugin on
Of course there are a lot more options. Surf the web for it.
I won't go into details how to use the VIM. It is well documented in VIM. Just type :help. Moreover there are many tutorials out there. I suggest the official VIMdoc and the great screencast at peep code.com. For getting further tips visit the VIM Runpaint

Freitag, 14. Dezember 2012

Ruby conventions: methods with ? and !

Today I cover the Ruby convention of using a question mark or exclamation mark in method names.
Following the convention eases the readability of Ruby codes.
The question mark is for methods returning boolean values, like:
class Language
  attr_accessor :name

  def initialize(name)
    @name = name
  end
  
  def downcased?
    name == name.downcase
  end
end
and:
language = Language.new "ruby"
language.downcased?
returns:
=> true

Next. The exclamation mark in Ruby methods. In general, methods with trailing "!" indicate that the method will modify the object it's called on. The ones without are called "safe methods", and they return a copy of the orignal with changes applied to the copy, with the callee unchanged. For example:
original = "RUBY"
copy = original.downcase
The variable:
copy
contains:
=> "ruby"
while:
original
is still:
=> "RUBY"
and please compare with trailing "!":
original = "RUBY"
copy = original.downcase!
The variable
copy
contains:
=> "ruby"
So a trailing "!" in a method name should mark that the object itself will be modified, when called. Syntactic sugar!
Supported by Ruby 1.9.3

Mittwoch, 12. Dezember 2012

Soft delete for ActiveRecord

Master data often require to be kept even if they are deleted by the user. One reason could be the requirement to be able to reactivate the record (RoR's ActiveRecord::Base). Another one could be to keep the references. No matter what the demand is. It's simple to solve.
I coded a module to reuse the logic and named it RecordActivation:
module RecordActivation
  extend ActiveSupport::Concern
  self.included do
    scope :active, where(:active => true)
    validates_presence_of :active
    before_validation :activate, 
      :on => :create, 
      :if => Proc.new { |r| r.active.nil? }
  end

  def activate
    self.active = true
  end
 
  def activate!
    activate
    save!
  end
  
  def deactivate
    self.active = false
  end
 
  def deactivate!
    deactivate
    save!
  end
end
As an example I created a Task migration:
class CreateTasks < ActiveRecord::Migration
  def change
    create_table :tasks do |t|
      t.string :name
      t.boolean :active
      t.timestamps
    end
  end
end
... and included the module into the model:
class Task < ActiveRecord::Base
  include RecordActivation
end
Let's go into detail in terms of the module.
Please notice that I extended my module with ActiveSupport::Concern. It resolves module dependencies and should be preferred when it comes to module handling. The second I want to point to, is the snippet which is run, when the module is included:
    scope :active, where(:active => true)
    validates_presence_of :active
    before_validation :activate, 
      :on => :create, 
      :if => Proc.new { |r| r.active.nil? }
It spends a scope to the Task model. So finding all active tasks means:
Task.active.all
If you want to ensure, that the activation flag is qualified, add the validation by validates_presence_of. Also make sure that the flag is set initially before creation by calling the method "activate" (but only if the value is not set already/ still NULL). By default all new created records are active.
Task.new.save!
... will create a new active task.
Four instance methods allow to set or reset the boolean flag. Those with an exclamation mark at the end of their name force the saving immediately (following the convention). For example:
Task.active.order("created_at").first.deactivate!
will deactivate the oldest task at the database.
That's all.
Supported by Ruby on Rails 3.2.8

Sonntag, 9. Dezember 2012

Rubies on RVM

Sometimes you are forced to switch your time-tested Ruby application to a newer Ruby version. You don't need to be scared. There is RVM, the Ruby Version Manager. It let you use different Rubies conveniently by just a simple command. You even can install several gemsets per Ruby version! It's easy to install:
user$ \curl https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer | bash -s stable
Please notice the backslash before curl. This prevents misbehaving if you have aliased it with configuration in your ~/.curlrc file. Make sure your current terminal session has loaded RVM:
user$ source ~/.rvm/scripts/rvm
When you open a new shell, RVM is loaded automatically. Test if your installation was successful:
user$ type rvm | head -n 1
rvm is a function
Your terminal should output: rvm is a function Finally, see if there are any dependency requirements for your operating system by running:
user$ rvm requirements
Installation done. Let's play around with certain Rubies. First install one, e.g. Ruby 1.9.2:
user$ rvm install 1.9.2
Use the crisp Ruby installation:
user$ rvm use 1.9.2
Check the version of your current Ruby:
user$ ruby -v
If you want to know which Ruby versions you already got on your RVM, list them:
user$ rvm list known
Set your favourite Ruby as default:
user$ rvm use 1.9.2 --default
One huge benefit of RVM is the possibility to install several named gemsets independent from your installed Ruby.
Create a gemset for Rails 3.2.9 (on your default Ruby 1.9.2):
user$ rvm gemset create rails_329
Use it:
user$ rvm use 1.9.2-head@rails_329
Install you first gem (Rails 3.2.9) on you gemset:
user$ gem install rails -v 3.2.9
List the gemsets on your current choosen Ruby:
user$ rvm gemset list
There are a lot more options for RVM (e.g. user installation or benchmarking your code against several versions of Ruby and many more). I just referred to only a few/ some of the most important.
For going into detail please visit the RVM page. There you also will find an answer, if you discovered an issue depending on your used OS. Anyway you should take a look.

Samstag, 8. Dezember 2012

From JavaScript to CoffeeScript

CoffeeScript makes you write clean and more readable JavaScript code. Syntactic sugar! Typically you'll code 30% less lines. Good to know the code compiles one-to-one into the equivalent JavaScript, and there is no interpretation at runtime. As a first example I convert the snippet of the cyclic remote link using jQuery into CoffeeScript. You can compare the simple logic in JavaScript and CoffeeScript yourself. First the code in JavaScript once again:
$(document).ready(function(){
    jQuery.each($('a.auto_remote'), function(){
     setInterval(function(remote_link) {
        $.ajax({ url: $(remote_link).attr('href') });
      }, 10000, this);
    });
});
In CoffeeScript it is tidy like this:
$(document).ready ->
  jQuery.each $("a.auto_remote"), ->
    setInterval ((remote_link) ->
      $.ajax url: $(remote_link).attr("href")
    ), 10000, this
The first that attracts attention is the syntactic sugar like Ruby, Python or Haskell also offer. No semicolons, less brackets, just more readable. Furthermore you noticed the alias "->" for functions. Practical:
$(document).ready(function(){
    // some codes
});
In CoffeeScript:
$(document).ready -> // some codes
... sweet.
Read the CoffeeScript Tutorial and check how your JavaScript looks like converted into CoffeeScript.
Supported by CoffeeScript 1.4.0

Mittwoch, 28. November 2012

Github is a cool cat

I assume you are comitted to the coolness of GIT. Installing GIT on a Debian based Linux is easy:
$ sudo apt-get -y install git-core
There are 2 options to host the code: On your own system or on Github.
I recommend the second choice. The infrastructure is already existing and Github furthermore includes simple ticketing to assist your development process. In the end it is free (Github is THE spot for social coding).
Github is a real cool cat.
So go on by setting the default name for GIT to use when you commit:
$ git config --global user.name "Your Name Here"
Set the default email for GIT to use when you commit:
$ git config --global user.email "your_email@youremail.com"
... your email address for Git should be the same one associated with your GitHub account. The last option we need to set will tell git that you don't want to type your username and password every time you talk to a remote server. To use this option, you need to turn on the credential helper so that git will save your password in memory for some time:
$ git config --global credential.helper cache
By default git will cache your password for 15 minutes. You can change this if you like. You can set the cache to timeout after 1 hour (setting is in seconds):
$ git config --global credential.helper 'cache --timeout=3600'
That's all. Now call on Github and launch your repository.

If you need further information go to: https://help.github.com/articles/set-up-git
or sign up your Github account directly: https://github.com/signup/free

Dienstag, 27. November 2012

Simple cyclic remote link using jQuery

Create a link in the view template you want to trigger a cyclic request:
<%= link_to 'Refresh', root_path, :remote => true, 
  :class => 'auto_remote' %>
I chose the root url as destination, but it should be the route you want to call. Then add a javascript snippet in your application.js (or the js file you use in the view):
$(document).ready(function(){
    jQuery.each($('a.auto_remote'), function(){
     setInterval(function(remote_link) {
        $.ajax({ url: $(remote_link).attr('href') });
      }, 10000, this);
    });
});
In my example the request is triggered every 10th second. Supported by Ruby on Rails 3.2.8 and JQuery 1.8.3