Translate

December 12, 2012

Class Variables on Class, in Ruby


Class variable

You can declare class variables by using @@ for prefix of variable name, for instance: @@common

A class variable is shared among all objects of a class, and it is also accessible to the class methods that we'll describe later. There is only one copy of a particular class variable for a given class
Class variables must be initialized before they are used. Often this initialization is just a simple assignment in the body of the class definition.
Class variables can easily overwrite by subclasses. This is based on Ruby specification; class variables can be shared on its subclass.
Class variables are similar with global variables. They're too hard to handle safely.
Ruby class variables are not really class variables at all, Apparently they are global to the class hierarchy. Changing a value in the subclass impacts the base classes. Generally speaking, globals and global-like things are bad, they are considered harmful

I'll try to explain problems around class variables in Ruby?

Class variable
You can declare class variables by using @@ for prefix of variable name.

class Share
  # Defining class variable on common
  @@common = :apple
   
  def share
    "Hello, you can have #{@@common}"
  end
   
  def common=(thing)
    @@common = thing
  end
end
 
share_1 = Share.new
puts share_1.share #=> "Hello, you can have apple"
 
share_1 = Share.new
# Share#common method replaces class variable @@common.
share_2.common = :mango
 
# ohh, this effects to other instance of class Share.
puts share_2.share #=> "Hello, you can have mango"


class Share
  @@common = :apple
end
 
# Declare new class Share inherits Fruit
class Share < Fruit
  # You can see superclass' class variable.
  puts @@common #=> :apple
 
  # Try to replace in subclass
  @@common = :mango
end
 
class Share
  # Above line effects to its superclass, Share!
  puts @@common #=> :mango
end

Summary:

Class variables are similar with global variables. They're too hard to handle safely.
For usually cases, I can't recommend to use. Ruby class variables are not really class variables at all, Apparently they are global to the class hierarchy. Changing a value in the subclass impacts the base classes. Generally speaking, globals and global-like things are bad, they are considered harmful

November 21, 2012

Ruby - block, Proc, lambda and method

Here is my brief explanation after reading about ruby closures.

Ruby does great stuffs with closure, like in array iteration we are using closures in everywhere.
Ruby has 4 type of closures - Block, Procs, Lambda and Method. I'm trying to explain them in brief.

Block
It's used with '&' sign prefixed variable also executes using yield or *.call.
1
2
3
4
5
6
7
def do_something_with(&block)
  puts "I did this with block using #{block.call}"
end
 
do_something_with {"ruby"}

#=> I did this with block using ruby

Procs (Procedures)
Its used as other ruby data types (array, hash, string, fixnum etc..), it's reusable and could be used across multiple calls. also several procedures could be passed at a time.
1
2
3
4
5
6
7
def do_something_with(block)
  puts "I did this with Proc using #{block.call}"
end
 
do_something_with Proc.new { "ruby" }
 
#=> I did this with Proc using ruby

Lambda's
It's a procedure (Proc) but with required parameter checking.
Also there is another difference between lambda and Proc. Proc's "return" will stop method and will return from Proc on the other hand lambda‘s "return" will only return it's own value to the caller method.
1
2
3
4
l = lambda {|a, b| ...}
l.call('A')

#=> Error need to pass 2 arguments

Example
1
2
3
4
5
6
7
def who_win_the_title?
  l = Proc.new { return "Rafael Nadal" }
  l.call
  return "Roger Federer"
end
 
#=> "Rafael Nadal"
Because Proc's return is just like method's own return. because it works like reusable code snippet.

Method
Method is another way around in ruby to use existing method as closure.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
def cheese
  puts 'cheese'
end
 
def say_cheese(block)
  block.call
end
 
say_cheese method(:cheese)
 
#=> cheese

I learned it from hear - http://www.robertsosinski.com/2008/12/21/understanding-ruby-blocks-procs-and-lambdas/

November 14, 2012

Rails On Ubuntu 12.10 Quantal Quetzal

Here's my quick guide to setting up Rails on Ubuntu 12.10 Quantal Quetzal

Step 1: Install Dependencies
The following two commands are going to upgrade any existing packages we have as well as install the dependencies we are going to need to build Ruby properly.

$sudo apt-get -y update && sudo apt-get -y upgrade

$sudo apt-get -y install build-essential zlib1g-dev libssl-dev curl libreadline-dev git-core libcurl4-openssl-dev libyaml-dev python-software-properties 

Step 2: Install Ruby 1.9.3
Grab the latest version of Ruby from ruby-lang.org
The following commands will download the Ruby source, extract it, configure and compile it, and then finally install Bundler.

wget ftp://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.3-p286.tar.gz
tar -xvzf ruby-1.9.3-p286.tar.gz
cd ruby-1.9.3-p286/
./configure
make
sudo make install
sudo gem install bundler


Step 3: Install Your Database
Choose the database you like.

Install Postgres 9.2

sudo apt-add-repository ppa:pitti/postgresql
sudo apt-get -y update
sudo apt-get -y install postgresql-9.2 libpq-dev

OR

Install MySQL 5.X.XX

sudo apt-get install mysql-server mysql-client libmysqlclient-dev

Step 4: Install Nginx and Passenger
To install Nginx, We will use Passenger's install script. Its simple and straight.

gem install passenger
passenger-install-nginx-module

Just choose the first option (1) to download and install it for you. Accept any defaults it suggests, like installation directories.
After installation is finished, you'll get some configuration tips for Nginx to use Passenger.
Since we are compiling nginx from source, we don't get the start/stop script from Ubuntu's package.
You can get an init script from Linode's website and install it.

wget -O init-deb.sh http://library.linode.com/assets/660-init-deb.sh
sudo mv init-deb.sh /etc/init.d/nginx
sudo chmod +x /etc/init.d/nginx
sudo /usr/sbin/update-rc.d -f nginx defaults

Once that's done, you can start and stop nginx like:

sudo /etc/init.d/nginx start
sudo /etc/init.d/nginx stop

Rails On Ubuntu 12.10

gem install rails

and get started.

October 8, 2012

Adding an nginx init script to auto start in Ubuntu

Assumption

I am assuming you have installed nginx from source using the default options.
If you have used other options or have place the nginx binary in a directory other than /usr/local/sbin/ then you may need to adjust the script shown below.

Stop

If you have nginx running then stop the process using:
sudo kill `cat /usr/local/nginx/logs/nginx.pid`

Init script

The script shown below is from an Ubuntu 10.04LTS install and has been adapted to take into account our custom install of nginx.
Let's go ahead and create the script:
sudo nano /etc/init.d/nginx

Inside the blank file place the following:
#! /bin/sh

### BEGIN INIT INFO
# Provides:          nginx
# Required-Start:    $all
# Required-Stop:     $all
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: starts the nginx web server
# Description:       starts nginx using start-stop-daemon
### END INIT INFO

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/local/sbin/nginx
NAME=nginx
DESC=nginx

test -x $DAEMON || exit 0

# Include nginx defaults if available
if [ -f /etc/default/nginx ] ; then
        . /etc/default/nginx
fi

set -e

case "$1" in
  start)
        echo -n "Starting $DESC: "
        start-stop-daemon --start --quiet --pidfile /usr/local/nginx/logs/$NAME.pid \
                --exec $DAEMON -- $DAEMON_OPTS
        echo "$NAME."
        ;;
  stop)
        echo -n "Stopping $DESC: "
        start-stop-daemon --stop --quiet --pidfile /usr/local/nginx/logs/$NAME.pid \
                --exec $DAEMON
        echo "$NAME."
        ;;
  restart|force-reload)
        echo -n "Restarting $DESC: "
        start-stop-daemon --stop --quiet --pidfile \
                /usr/local/nginx/logs/$NAME.pid --exec $DAEMON
        sleep 1
        start-stop-daemon --start --quiet --pidfile \
                /usr/local/nginx/logs/$NAME.pid --exec $DAEMON -- $DAEMON_OPTS
        echo "$NAME."
        ;;
  reload)
      echo -n "Reloading $DESC configuration: "
      start-stop-daemon --stop --signal HUP --quiet --pidfile /usr/local/nginx/logs/$NAME.pid \
          --exec $DAEMON
      echo "$NAME."
      ;;
  *)
        N=/etc/init.d/$NAME
        echo "Usage: $N {start|stop|restart|force-reload}" >&2
        exit 1
        ;;
esac
exit 0
There's not really the space to go into the workings of the script but suffice to say, it defines where the main nginx binary is located so nginx can be started correctly.
It also defines where to find the nginx.pid file so the process and be correctly stopped and restarted.

Execute

As the init file is a shell script, it needs to have executable permissions.
We set them like so:
sudo chmod +x /etc/init.d/nginx

update-rc

Now we have the base script prepared, we need to add it to the default run levels:
sudo /usr/sbin/update-rc.d -f nginx defaults

The output will be similar to this:
Adding system startup for /etc/init.d/nginx ...
   /etc/rc0.d/K20nginx -&gt; ../init.d/nginx
   /etc/rc1.d/K20nginx -&gt; ../init.d/nginx
   /etc/rc6.d/K20nginx -&gt; ../init.d/nginx
   /etc/rc2.d/S20nginx -&gt; ../init.d/nginx
   /etc/rc3.d/S20nginx -&gt; ../init.d/nginx
   /etc/rc4.d/S20nginx -&gt; ../init.d/nginx
   /etc/rc5.d/S20nginx -&gt; ../init.d/nginx
Done.

Start, Stop and Restart

Now we can start, stop and restart nginx just as with any other service:
sudo /etc/init.d/nginx start
...
sudo /etc/init.d/nginx stop
...
sudo /etc/init.d/nginx restart
The script will also be called on a reboot so nginx will automatically start.

Summary

Adding a process to the run levels like this saves a lot of frustration and effort, not only in manually starting and stopping the process, but it having it automatically start on a reboot.

September 21, 2012

Rails 4 Highlights

Rails 4 Highlights

Rails 4 Highlights

  • StrongParameters: replaces attr_accessor, attr_protected, moves param filtering concern to the controller rather than the model. Moving param filtering concern to the controller allows you to more easily modify user attribute change-ability in controllers (e.g. customer-facing vs admin).

  • ActiveSupport::Queue: Add queueing support to Rails, like:

      # Add to queue
      Rails.queue.push UserRegistrationMailerJob(@user.id)
    
      # Control queue configuration (asynchronous, synchronous or resque, e.g.
    config.queue = [:asynchronous, :synchronous, :resque]
    
  • Cache Digests: Rails 4.0 introduces cache key generation based on an item and its dependencies, so nested cache elements properly expire when an item is updated.

  • Improvements to ActiveRecord::Relation

    • Relation.all: returns ActiveRecord::relation object. User.all => User.to_a
    • Relation.none: Returns ActiveRecord::NullRelation , still chain.
    • Relation.___!: mutates current relation, e.g.@users.where!, @users.include!
  • Deprecations

    • AR::Base.scoped
    • Dynamic Finder Methods: e.g. find_all_by_ *
    • Hash-based Finders: e.g. User.find(:first)
    • Eager Evaluated Scope: scope will require a lambda
    • ActiveRecord::SessionStore
    • ActiveResource
    • Rails::Plugin
  • PATCH verb support: Support of HTTP PATCH method (_method equals "patch"), which will map to your update action is introduced in Rails 4.0.

  • Routing Concern: Rails 4.0 introduces some methods to help clean up your duplicate routes.

  • Deprecation Policy: Many of the above deprecations will still work in Rails 4.0 and included as gem dependencies, but will be removed in the jump to Rails 4.1. This means that the upgrade to Rails 4.1 may be more painful than the upgrade to Rails 4.0.

August 29, 2012

How to install Ruby on rails in Windows 7

Introduction:
This is a step by step tutorial that will let you install Ruby on rails 3 in your Windows 7. These steps ease the installation process.

Steps:
  • Download Ruby Windows installer from ruby-lang.org
  • Select version 1.9.3, which is the most recommended and stable release for Windows. 
    When installing this software, make sure to check "Add Ruby to PATH".
  • After installing Ruby, open CMD and check if you Ruby is accessible by executing the following command:
  • ruby -v

    If it works fine you should see the version number of Ruby
  • Then check if you can access gem command by executing:
  • gem -v
  • As you will see, probably the gem version installed by default if this is not the latest, you need to update gem like this:
  • gem update --system
  • Now you are ready to install Ruby on rails, without rdoc and ri documents. By executing following command
  • gem install rails --no-ri --no-rdoc

    Ruby on rails works with SQLite by default but we will use MySQL.
  • In order to let you use both, let us download SQLite and then configure MySQL.  Download SQLite dlls from sqlite.org, unzip them and copy them to:
  • c:\<your_ruby_dir>\bin
  • Now you should install SQLite gem:
  • gem install sqlite3-ruby
  • Now it is time for MySQL. Go to the MySQL website and download the community edition and after installing it in your OS, download this libMySQL.dll and copy it into the same location you put the SQLite dlls
  • c:\<your_ruby_dir>\bin
  • Now install the MySQL gem. To install the mysql gem execute:
  • gem install mysql
  • Now we are ready to create a testing project in rails. Since we are going to use MySQL as DB, we should then execute:  
  • rails new my_first_project -d mysql

August 15, 2012

Missing gcc-4.2 on Mountain Lion

Missing gcc-4.2 on Mountain Lion

I've seen reports of missing /usr/bin/gcc-4.2 on OSX 10.8 (Mountain Lion). Some have tried to reinstall xCode and that worked for them.

I got this when I was trying to install gem
    make
    ....
    make: /usr/bin/gcc-4.2: No such file or directory
    make: *** [bcrypt_ext.o] Error 1
    

Executing following command solved problem on my system.

sudo ln -s /usr/bin/gcc /usr/bin/gcc-4.2

apple-gcc42 installs its gcc-4.2 binary into /usr/local/bin (or wherever you installed Homebrew), not /usr/bin.
Your ruby gems are probably trying to use gcc-4.2 because ruby configures itself to build C extensions with whichever compiler built ruby itself. If you built ruby using gcc-4.2 on an older version of Xcode when that still came with gcc-4.2, that would explain why it's looking for that specific path. Reinstalling ruby with /usr/local/bin/gcc-4.2 would fix the problem.

Note: Linking /usr/bin/gcc to /usr/bin/gcc-4.2 is not perfect way, This is simple trick.

August 14, 2012

Install RVM, Ruby, Ruby on Rails on OS X Mountain Lion 10.8

OS X Mountain Lion was released for all users in the Mac App Store.
Here are some of the things you should consider as you make the switch to this shiny new operating system.

After I downloaded the 4GB installer from the Mac App Store, the whole upgrade process took me about 45 minutes on my 13" 2012 Macbook Pro. It was a simple and straightforward process as the installer takes care of everything.

Once the installer is done, we need to do some additional work to get up to speed once again and be able to compile Ruby (using RVM) or install packages using Homebrew.

Install Xcode + Command Line Tools
You can get Xcode from the Mac App Store. You'll need at least version 4.4 of Xcode for it to work with OS X Mountain Lion. After the installation, open up Xcode in your /Applications folder. You'd want to go to Xcode -> Preferences -> Downloads tab then install the "Command Line Tools". After you're done, quit Xcode and fire up Terminal.

After the upgrade, Apple will set the ownership of your /usr/local folder to root. You can easily fix this by running this command in Terminal:

sudo chown -R `whoami` /usr/local

Next, you need to update Homebrew:

brew update

To install any Ruby that's older than 1.9.3 like 1.9.2, 1.8.7 etc.
You'll need to install GCC 4.2. Apple does not ship the Command Line Tools with gcc-4.2 compiler anymore,
You need to install it via Homebrew. By default, Homebrew doesn't include any formula that ships with the OS in the main repository, so you'll have to enable homebrew-dupes repository by using brew tap

  brew tap homebrew/dupes
  brew install apple-gcc42 

If you were using a binary package from MySQL website to install your MySQL server, you will need to change the ownership of your MySQL data directory back by issue this command:
sudo chown -R mysql:mysql `brew --prefix`/mysql
Word to the Wise: Backup Your System
Before performing any major upgrade, always make sure that you have the latest backup of your Mac.

August 10, 2012

*** Textmate 2 - Open Sourced ***

One of most known code/text editors on OS X went open source. Since yesterday TextMate 2 is available on GitHub.

Allan Odgaard's TextMate has been a beloved text editor since 2004 and one of gem of Mac's favorite apps for about just as long, but since 2009, development on the app has slowed to a crawl: three years ago, Odgaard said TextMate 2 was about 90% complete, but it didn't hit the web until end of year 2011, also a final version still hasn't been released.

In a surprise (and very awesome move), its source code has: TextMate 2 is going open source.

If you're interested in tinkering or even compiling TextMate 2 for yourself, you can grab it on GitHub.

Legal
The source for TextMate is released under the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
TextMate is a trademark of Allan Odgaard.

July 26, 2012

OS X 10.8 Mountain Lion

Apple have released their latest addition to the OS X family with version 10.8, also known as "Mountain Lion". This new version brings with it a whole host of improvements, most of which focus on bringing features such as the Notification Center and iCloud from iOS to the Mac. In addition to those new features, 10.8 also includes system wide refinements, which make the OS feel like what Lion should have been.

The inclusion of some new apps which started their lives on iOS. If you've used iOS before, these "new" apps shouldn't really feel all that "new". Notes, Reminders, and, Game Center are all nearly identical clones of their iOS counterparts, with a more grown up feel on the Mac desktop.

You can store the notes you create either locally or sync them with iCloud. Reminders works just like you'd expect, and is even is able to tap into your location (presumably based on your WiFi and IP address) and deliver reminders either when arriving at or leaving a location. Similar to the iOS version of the app, Reminders also lets you set reminders for a specific date and time. 

End users now have a notification system that is both integrated and easy to use, and programmers have one consistent way for their apps to send notifications.

-It includes the ability to mirror your Mac's screen to an AppleTV or any other AirPlay receiver.

-Users with an AppleTV on the same WiFi network as their Mac will notice an AirPlay icon appear in the bar; simply click the icon and select your AppleTV to get started. You will see your Mac's desktop on the big screen. (WoW)

-New improved Messages

-Better iCloud File sharing

- Enhanced sharing capabilities - From the "Mail, Contacts & Calendars" screen in System Preferences, users can now set up Twitter, Facebook, Flickr, and Vimeo accounts with the OS.

OS X Mountain Lion includes system-wide refinements for just about every app. After installing the OS on my computer, everything just seemed to work a little bit better. 

May 1, 2012

Howto- Install PostgreSQL in Ubuntu 11.10/12.04

  • Install PostgreSQL in Ubuntu, some instructions are given below, Install postgresql using the command on terminal:
  • sudo apt-get install postgresql  libpq-dev
    
  • By default postgres is listening on port 5432. You need to confirm that after installation check that postgres is listening on port 5432
  • To check postgres is really listening on port 5432 use following command on terminal:
  • netstat -atn | grep -v tcp6 | grep 5432                          
    tcp 0 0 127.0.0.1:5432 0.0.0.0:* LISTEN  
    
  • If you see above output, then postgres is installed successfully on your system. You need other configurations to interact with postgres. First you need to create new db user to access the postgres, Default db user postgres is created when you install the postgres.
  • Now change the postgres user password (as root):
  • Make first database user (a superuser is required for practical migrations) in postgres!:
    sudo su postgres                                                   
    createuser pankaj                                                  
    Shall the new role be a superuser? (y/n) y
    
  • Now create a postgres database Create a first postgres development database
  • ~> pssql template1 
    psql (9.1.3)
    Type "help" for help.
    
    template1-# \l
                                      List of databases
       Name    |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges   
    -----------+----------+----------+-------------+-------------+-----------------------
     postgres  | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
     template0 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
               |          |          |             |             | postgres=CTc/postgres
     template1 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
               |          |          |             |             | postgres=CTc/postgres
    (3 rows)
    
    template1-#
    
    template1=# CREATE DATABASE dummy_development;
    CREATE DATABASE
    template1=#
    template1=# \l
                                         List of databases
           Name       |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges   
    ------------------+----------+----------+-------------+-------------+-----------------------
     postgres         | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
     dummy_development| pankaj   | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
     template0        | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
                      |          |          |             |             | postgres=CTc/postgres
     template1        | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
                      |          |          |             |             | postgres=CTc/postgres
    (4 rows)
    
    template1=#\q
    
    ------ TO Quit use \q
    
Ruby on Rails developers:
  • Install the postgres gem
  • dummy git:master> gem install pg                      
    Building native extensions.  This could take a while...
    Successfully installed pg-0.13.2
    
  • To install GUI client pgsql
  • sudo apt-get install pgadmin3
    

April 18, 2012

Difference between update_attribute and update_column


We use update_attribute most of the time, update_column serves same purpose, there is below difference
  • update_attribute
  • It updates the single attribute with bypassing the validations.
  • update_column
  • It updates the single attribute with bypassing the validations as well as the callbacks.

Syntax of both are as follow:
Model.update_attribute :field, 'value'
Model.update_column :field, 'value'

update_column is added in the rails 3.2.1

In case if you need to use update_column in lower Rails version then you can apply simple patch given below.

module ActiveRecord
  module AttributeMethods
    def update_column(name, value)
      name = name.to_s
      self.class.update_all({ name => value }, self.class.primary_key => id) == 1
     end
   end
end

Related posts:
Difference between update_attribute and update_column 
What is different in update_all, update,  update_attribute, update_attributes methods of Active Record
Difference between .nil?, .empty?, .blank?, .present? 
render vs redirect_to in Ruby on Rails

About

April 17, 2012

What is different in update_all, update, update_attribute, update_attributes methods of Active Record

We use Active Record update* methods regularly, following text explains the difference between all update* the methods

update(id,attributes)
Update single or multiple objects using update method of active record. When update method is called it invokes model based validation, and save the object when validation passes successfully else object is not save.
It accepts two arguments, id and attributes which need to update.
User.update(1,:first_name => "John",:last_name => "Turner")
same way you are able to update multiple objects.
User.update([1,2],[{:first_name => "John",:last_name => "Turner"},{:department => "admin"}])

update_all(attribute, conditions, options)
It updates the given attribute of object by invoking specified conditions and options like order, limit. This will not invoke validation rules, methods of the model.
User.update_all("department = admin, "user_role Like '%admin'",:limit => 10)

update_attribute
This method update a single attribute of object without invoking model based validation.
user = User.find_by_id(params[:id])
user.update_attribute :role,"admin_manager"

update_attributes
This method update multiple attribute of single object and also pass model based validation.
attributes = {:first_name => "Peter", :age => 30}
user = User.find_by_id(params[:id])
user.update_attributes(attributes)

I think this article helped you to understand different Active Record update* methods. And which method to use in specific situation.
If have any query or suggestion than simply leave the comment.

Related posts:
Difference between update_attribute and update_column 
What is different in update_all, update,  update_attribute, update_attributes methods of Active Record
Difference between .nil?, .empty?, .blank?, .present? 
render vs redirect_to in Ruby on Rails

About