rake -T does not list my custom rake task

This is just a tip, may be you guys are already aware of it.

Sometimes I wonder why my custom rake task doesn’t appear in rake -T list, however it runs well. I just noticed that if I do not specify description for a task then that particular rake task does not appear in the task list.

Ruby 1.9.1: Hash

In ruby 1.9.1 has many changes for Hash some useful changes are below:

RUBY_VERSION => 1.8.6

RUBY_VERSION => 1.9.1

>> {'name', "Akhil"}
=> syntax error, unexpected ',', expecting tASSOC

>> {name: "Akhil"}
=> {:name=>"Akhil"}

Now Hash preserves order:

RUBY_VERSION => 1.8.6

>> hash = {:a=> 'A', :b=>'B', :c=>'C', :d=>'D'}
=> {:b=>"B", :c=>"C", :d=>"D", :a=>"A"}
>> hash.to_a
=> [[:b, "B"], [:c, "C"], [:d, "D"], [:a, "A"]]
>> hash.keys
=> [:b, :c, :d, :a]
>> hash.values
=> ["B", "C", "D", "A"]

RUBY_VERSION => 1.9.1

>> hash = {:a=> 'A', :b=>'B', :c=>'C', :d=>'D'}
=> {:a=>"A", :b=>"B", :c=>"C", :d=>"D"}
>> hash.to_a
=> [[:a, "A"], [:b, "B"], [:c, "C"], [:d, "D"]]
>> hash.keys
=> [:a, :b, :c, :d]
>> hash.values
=> ["A", "B", "C", "D"]

Better to_s method(similar to hash.inspect).

RUBY_VERSION => 1.8.6

>> hash = {:a=> 1, :b=>2, :c=>3, :d=>4}
=> {:b=>2, :c=>3, :d=>4, :a=>1}
>> hash.to_s
=> "b2c3d4a1"

RUBY_VERSION => 1.9.1

>> hash = {:a=> 1, :b=>2, :c=>3, :d=>4}
=> {:a=>1, :b=>2, :c=>3, :d=>4}
>> hash.to_s
=> "{:a=>1, :b=>2, :c=>3, :d=>4}"

hash.each and hash.each_pair

RUBY_VERSION => 1.8.6

>> hash = {:a=> 1, :b=>2, :c=>3, :d=>4}
=> {:b=>2, :c=>3, :d=>4, :a=>1}
>> hash.each{|x| p x}
[:b, 2]
[:c, 3]
[:d, 4]
[:a, 1]
=> {:b=>2, :c=>3, :d=>4, :a=>1}
>> hash.each_pair{|x| p x}
(irb):48: warning: multiple values for a block parameter (2 for 1)
        from (irb):48
[:b, 2]
(irb):48: warning: multiple values for a block parameter (2 for 1)
        from (irb):48
[:c, 3]
(irb):48: warning: multiple values for a block parameter (2 for 1)
        from (irb):48
[:d, 4]
(irb):48: warning: multiple values for a block parameter (2 for 1)
        from (irb):48
[:a, 1]
=> {:b=>2, :c=>3, :d=>4, :a=>1}

RUBY_VERSION => 1.9.1

>> hash = {:a=> 1, :b=>2, :c=>3, :d=>4}
=> {:a=>1, :b=>2, :c=>3, :d=>4}
>> hash.each{|x| p x}
[:a, 1]
[:b, 2]
[:c, 3]
[:d, 4]
=> {:a=>1, :b=>2, :c=>3, :d=>4}
>> hash.each_pair{|x| p x}
[:a, 1]
[:b, 2]
[:c, 3]
[:d, 4]
=> {:a=>1, :b=>2, :c=>3, :d=>4}

hash.select now returns hash instead of array

RUBY_VERSION => 1.8.6

>> hash = {:a=> 1, :b=>2, :c=>3, :d=>4}
=> {:b=>2, :c=>3, :d=>4, :a=>1}
>> hash.select{|k,v| k == :c }
=> [[:c, 3]]

RUBY_VERSION => 1.9.1

>> hash = {:a=> 1, :b=>2, :c=>3, :d=>4}
=> {:a=>1, :b=>2, :c=>3, :d=>4}
>>  hash.select{|k,v| k == :c }
=> {:c=>3}

Tip: Open DB shell/console from rails root dir

Just a quick tip you might be using this already.

If you guys want to open your app’s DB shell. Then you can use rails utility ‘dbconsole’ by issuing “script/dbconsole” from rails root directory.

It will ask for DB password, and open your db shell.

If you use sake, you may like following sake task:

desc 'Launches the database shell using the values defined in config/database.yml'
task 'db:shell', :needs => [ 'environment' ] do
  config = ActiveRecord::Base.configurations[(RAILS_ENV or "development")]
  command = ""
  case config["adapter"]
  when "mysql" then
    (command << "mysql ")
    (command << "--host=#{(config["host"] or "localhost")} ")
    (command << "--port=#{(config["port"] or 3306)} ")
    (command << "--user=#{(config["username"] or "root")} ")
    (command << "--password=#{(config["password"] or "")} ")
    (command << config["database"])
  when "postgresql" then
    puts("You should consider switching to MySQL or get off your butt and submit a patch")
  else
    (command << "echo Unsupported database adapter: #{config["adapter"]}")
  end
  system(command)
end

quick_scopes: Rails plugin to automatically add some quick named_scopes to your models

Today I came across a new plugin named quick_scopes, and thought you guys might be interested to give it a try. Checkout http://github.com/internuity/quick_scopes/tree/master

ActionMailer Error: hostname was not match with the server certificate

You guys may have stuck with following error while using ActionMailer with Rails 2.2.2 .

OpenSSL::SSL::SSLError (hostname was not match with the server certificate):
    /usr/lib/ruby/1.8/openssl/ssl.rb:123:in `post_connection_check'
    /usr/lib/ruby/1.8/net/smtp.rb:582:in `tlsconnect'
    /usr/lib/ruby/1.8/net/smtp.rb:562:in `do_start'
    /usr/lib/ruby/1.8/net/smtp.rb:525:in `start'
    /vendor/rails/actionmailer/lib/action_mailer/base.rb:671:in `perform_delivery_smtp'
    /vendor/rails/actionmailer/lib/action_mailer/base.rb:526:in `__send__'
    /vendor/rails/actionmailer/lib/action_mailer/base.rb:526:in `deliver!'
    /vendor/rails/actionmailer/lib/action_mailer/base.rb:392:in `method_missing'
    /app/controllers/users_controller.rb:40:in `send_email_to_confirm_user'

Actually, Rails 2.2.2 turn on STARTTLS if it is available in Net::SMTP (added in Ruby 1.8.7) and the SMTP server supports it.

If you use postfix, then you fix it quickly by disabling tls by setting “smtpd_use_tls=no” in /etc/postfix/main.cf .

Remember to restart postfix and rails app server.

Testing ActiveScaffold based Controllers

If we are using ActiveScaffold in a controller, we might want to write test for that controller too. So we can write functional tests for all action that ActiveScaffold added to our controller like index, create, edit, update etc…

Since all these action are added by ActiveScaffold then these tests must go with ActiveScaffold plugin tests itself and I think they are at their place.

So we just need to test that ActiveScaffold is configured for that particular controller and uses the right model by:

assert_not_nil CampusController.active_scaffold_config
assert CampusController.active_scaffold_config.model == Campus

Ofcourse, we also need to write tests for custom actions added by us.

Generating association while generating model

May be you guys are already aware of, but in Rails 2.2 we can specify belongs_to association while generating model. So if we issue:

script/generate model Post title:string author:belongs_to

We will get a Post model like:

class Post < ActiveRecord::Base
  belongs_to :author
end

Also it will automatically add the foreign key column in the migration.

class CreatePosts < ActiveRecord::Migration
  def self.up
    create_table :posts do |t|
      t.string :title
      t.belongs_to :author

      t.timestamps
    end
  end

  def self.down
    drop_table :posts
  end
end

Nothing much but saves some keystrokes. :-)

Using Amazon SimpleDB with Rails

Last week I tried to use simpleDB with rails, here are some slides I prepared:

Ruby script to install bulk gems

Recently I had to setup many rails servers and for that I had to install some gems again and again by issuing traditional “gem install xyz” command several times. This was actually very annoying.

To avoid issuing “gem install xyz” command again and again, while setting up new machine, I wrote a utility script in ruby. This script read a list of gems and install them by avoiding ri and rdoc installation for gem.

This script saved lots of my time. Here is the Ruby script to install bulk gems, if you would like to give it a try.

Download this script and save as .rb. Run this script by “ruby install_gems.rb” and follow the instructions on screen.

Skiping installation of ri and RDoc documentation while installing gems

Probably most of the time you would like to skip ri and RDoc installation while installing some new gems, specially on production server.

I do like to skip ri and RDoc documentation while installing gems on my development machine, because it takes more time to generate ri and RDoc then actual installation of gem.

We can skip rdoc and ri documentation while installing a gem by:

gem install rails --no-ri --no-rdoc

I am sure that you would not like to give –no-ri and –no-rdoc every time you install a gem. To avoid this situation, you can create/update $HOME/.gemrc file with following option:

gem: --no-ri --no-rdoc

Now every time you install a gem, it will skip installation of ri and RDoc for the gem.

My .gemrc file looks like:

---
:update_sources: true
:sources:
- http://gems.rubyforge.org/
- http://gems.github.com
:benchmark: false
:bulk_threshold: 1000
:backtrace: false
:verbose: true
gem: --no-ri --no-rdoc