Finally the long waiting rails 2.2 is released.

Referring to riding rails latest blog post , rails 2.2.2 released at November 21, 2008.

As we have tried the 2.2.1 version, i have solved rubygems upgrade problem. for rubygems 1.1 or 1.2 folks you may try :

$ gem install rubygems-update  (again, might need to be admin/root)
$ update_rubygems              (... here too)

After successfully updated, we may try out the gem install rails and it would succesfully installed :

apple-computer:~ tszkan$ sudo gem install rails -v 2.2.2
Successfully installed activesupport-2.2.2
Successfully installed activerecord-2.2.2
Successfully installed actionpack-2.2.2
Successfully installed actionmailer-2.2.2
Successfully installed activeresource-2.2.2
Successfully installed rails-2.2.2
6 gems installed
Installing ri documentation for activesupport-2.2.2...
Installing ri documentation for activerecord-2.2.2...
Installing ri documentation for actionpack-2.2.2...
Installing ri documentation for actionmailer-2.2.2...
Installing ri documentation for activeresource-2.2.2...
Installing RDoc documentation for activesupport-2.2.2...
Installing RDoc documentation for activerecord-2.2.2...
Installing RDoc documentation for actionpack-2.2.2...
Installing RDoc documentation for actionmailer-2.2.2...
Installing RDoc documentation for activeresource-2.2.2...
apple-computer:~ tszkan$ ls

Besides my most waiting feature i18n support, here have some more christmas present from rails 2.2, include HTTP validators, thread safety, JRuby/1.9 compatibility, docs

we will try upgrading existing project to 2.2 , stay tuned.

HACKs on acts_as_audited plugin

31 Aug 2008 In: Ruby On Rails

Audit Trail
At many cases, we have a use case called “Please keep all changes as history, showing who had created, or updated such record and log the time s/he did that” — This is a typical audit trail task in a very common system.

“Tommy created Products at 2008-08-20″ and “Thomas updated Orders at 2008-08-30 with Price set to $100″
In rails, we have many cool plugins for doing this features. Some would log all the version you made to that particular model, or have the feature that you can revert the version back. In the current project, we simply need an audit statement but not the revision feature. No need to rollback….it is too fancy.

acts_as_audited

Act as versioned: http://wiki.rubyonrails.org/rails/pages/ActsAsVersioned

Act as audited: http://opensoul.org/2006/7/21/acts_as_audited

We have compared act as versioned and act as audited and finally made some hacks on the act as audited plugin.

As we use RESTful_authenticated for our customer model and administrator model, the plugin automatically draw the user_type to Administrator or User, while the username field is left out. We have done some hack to the plugin to log the ip address when the user is not logged in and store the ip into the field username.

Here is the hack:
in lib/acts_as_audited.rb, pass also the ip address to the username field

def audit_create(user = nil, ip = nil)
write_audit(:action => 'create', :changes => audited_attributes, :user => user, :username => ip)
end
def audit_update(user = nil, ip = nil)
unless (changes = changed_audited_attributes).empty?
write_audit(:action => 'update', :changes => changes, :user => user, :username => ip)
end
end
def audit_destroy(user = nil, ip = nil)
write_audit(:action => 'destroy', :user => user, :username => ip)
end

in audit_sweeper.rb, retrieve the ip address from the request

def after_create(record)
# username field is HACKed to store the ip address
ip = request.remote_ip rescue ip = 'Unknown'
record.send(:audit_create, current_user, ip)
end
def after_destroy(record)
ip = request.remote_ip rescue ip = 'Unknown'
record.send(:audit_destroy, current_user, ip)
end
def before_update(record)
ip = request.remote_ip rescue ip = 'Unknown'
record.send(:audit_update, current_user, ip)
end

In addition, a namescope is added to the audit.rb to retrieve a particular admin’s history on particular model:

# name scope for retrieving a particular admin's history on particular model
named_scope :history, lambda {|model,admin| {:conditions => ['user_type = ? and user_id = ? and auditable_type = ? ', 'Administrator' , admin, model]}}

Acts As Taggable On Steroids is based on acts_as_taggable by DHH but includes extras such as

tests, smarter tag assignment, and tag cloud calculations.

For a number of applications, especially our Tutor Social Platform - Tutor Metro,  We’ve found a need for advanced tagging functionality not offered by the acts_as_taggable_on_steroids plugin.

for instance, we will wished a model could have multiple “sets” of tags that would function both independently and together and named scope support

That’s where acts_as_taggable_on comes in.

From mbleigh :

For instance, in a social network, a user might have tags that are called skills, interests, sports, and more. There is no real way to differentiate between tags and so an implementation of this type is not possible with acts as taggable on steroids. Enter Acts as Taggable On. Rather than tying functionality to a specific keyword (namely “tags”), acts as taggable on allows you to specify an arbitrary number of tag “contexts” that can be used locally or in combination in the same way steroids was used.

To install, that is very simple from the project site, however, if we want to migrate from taggable on steroids in previous project, we have to do some more tweaking :

1. install gems or plugin as normal

2. generate the migration as usual

script/generate acts_as_taggable_on_migration

3. suppose you have an acts_as_taggable migration before, we have to do less in this migration .  modify the migration as following


class ActsAsTaggableOnMigration < ActiveRecord::Migration


def self.up
remove_index :taggings, [:taggable_id,:taggable_type]
add_column :taggings, :tagger_id, :integer
add_column :taggings, :tagger_type, :string
add_column :taggings, :context, :string
  t.column :tagger_id, :integer
  t.column :tagger_type, :string
  t.column :context, :string
create_table :tags do |t|
  t.column :name, :string
end
create_table :taggings do |t|
  t.column :tag_id, :integer
  t.column :taggable_id, :integer
  t.column :tagger_id, :integer
  t.column :tagger_type, :string
  # You should make sure that the column created is
  # long enough to store the required class names.
  t.column :taggable_type, :string
  t.column :context, :string
  t.column :created_at, :datetime
end
add_index :taggings, :tag_id
add_index :taggings, [:taggable_id, :taggable_type, :context] , :name => ‘index_taggings’
end


def self.down
remove_index :taggings, :name => 'index_taggings'
add_index :taggings, [:taggable_id, :taggable_type]
remove_column :taggings, :tagger_id
remove_column :taggings, :tagger_type
remove_column :taggings, :context
drop_table :taggings
drop_table :tags
end


end

4. rake db:migrate

5. add parameters to the acts_as_taggable_on

class Photo < ActiveRecord::Base  acts_as_taggable_on :tagsend

6. fix your code on getting the tag list

7. do your testing, and you may have it done, cheer !

“Awesome” Nested Set

22 Aug 2008 In: Ruby On Rails

During the development of our latest product, we have to store a set of data in a tree structure. Usually we would implement the tree in nested set, if we found that we usually fetch the tree but not update the tree. Nested Set structure would have a bigger overhead if we do update on the tree but it is excellent in fetching, the main reason is that when we do update on the tree, we would index the entire tree again.

What is Nested Set?

Nested Set is a hierarchical data structure that store your data as a tree in the database. For more detail, you could go here http://dev.mysql.com/tech-resources/articles/hierarchical-data.html

Nested Set Plugin for RoR

We have implemented Nested Set in many projects, we make use of plugin, which give us handy functions to manipulate our “tree”. We used old plugin acts_as_nested_set, and then use better_nested_set (which is to replace the old one).

These day when we work on our latest project, we found that there is a latest plugin named awesome_nested_set, which is to replace all its previous version.

We just wonder will there be any “amazing_nested_set” or “it_is_really_fuking_amazing_nested_set” later on. =p

btw, this plugin is really awesome.

TutorMetro.com is on alpha

6 Aug 2008 In: Project, Ruby On Rails

After a session of development, our web site www.tutormetro.com is finally out in alpha release.

TutorMetro.com got an internal project code: pilot, which is aimed at providing a free tuition referral platform to local market.「名師」is the Chinese Name of tutormetro.com which represent the high quality of the tutors listed in the site.

TutorMetro.com is built solely on Ruby on Rails 2.0+, we enjoyed the development process on rails and we are still working on the TutorMetro.com and other cool rails projects.

Give a register on TutorMetro, and report us bugs if there is any ;)

BDD Behaviour Driven Development

19 Jul 2008 In: Ruby On Rails

In Hong Kong, as a fast moving city, “urgent” is one of the most common requirement from the clients. They require the most “cost-effective” way to implement systems and with a marginal price. For these low budget (but urgent) projects, some of the local software houses would simply deliver a “just-to-requirement” and “not-well-tested” solution to the client — the result is poor client satisfaction.

What we believe is — quality software is the base of the success of one software company. Therefore, we strictly adopt the agile development process and BDD is one of the testing approach we used.

In order to perform effective testing across increasing complex application, we adopted BDD in our projects. Some of the developers are lazy to write test cases throughout the development as they found that some test cases are meaningless to be written. When the application complexity increases, testing would be the harshest part of the development process.

Here is an example of “meaningless” test case:

class UserTest < Test::Unit::TestCase
def test_create
user = User.create(:some => ‘params’)
assert user.save
end
end

In this kind of test case which we regard as “meaningless” because it tests on the framework but not our own code. What we need is an effective testing across our codes.

Some Background

What is BDD? Behaviour Driven Development is an Agile development process that comprises aspects of Acceptance Test Driven Planning, Domain Driven Design and Test Driven Development.

RSpec is a BDD tool aimed at TDD in the context of BDD. And as our application is mainly built on Ruby on Rails, what we need is RSpec and RSpec on Rails plugins for our applications.

For more details on BDD: http://en.wikipedia.org/wiki/Behavior_driven_development

And more details for RSpec: http://rspec.info/

To install the plugin of RSpec and RSpec on Rails, what we need is to go here

http://github.com/dchelimsky/rspec-rails/wikis/home

but for the latest version (v 1.1.4) it only offers git repos to install, and we get some time to install the git into our system (as we have sticked to svn for long)……

We uses RSpec for testing as it is somehow more realistic to test the application on the “behaviour” instead of unit. Here is a piece of test case we wrote to illustrate the ellegance of the BDD:

describe Bid do
it ’should create reference id automatically’ do
@bid = Bid.new
@bid.reference_id.should_not be_nil
end
end

It is a test case to test whether the ‘reference_id’ would be created automatically when we ‘new’ the Bid object. We are testing on the application behaviour rather than testing whether we can create the object.

Here is the result, printing in a nice specdoc format:

$ spec spec/models/bid_spec.rb –format specdoc
Bid
- should create reference id automatically
Finished in 0.138937 seconds
1 example, 0 failures

btw, git is the next part we should spend time to explore, probaby after we finish some important client’s projects….

Unpacking Apple iPhone 3G 16Gb White

14 Jul 2008 In: Uncategorized

This is the latest Apple iPhone 3G 16Gb White color in our hands.

Fast and smooth unpacking.

All our staffs use iPhone, no matter it is 2G or 3G and iPhone really helps increasing our productivity by allowing us to work anywhere, anytime.

Tutormetro uses Google Apps For Your Domain, and all email flows throw Google’s servers. Unfortunately, Rails 1.2.2 or later cannot send via smtp.google.com out of the box as it use tls, which standard ruby package is not included.

There is a solution from http://railsforum.com/viewtopic.php?id=12875 .We have deployed and tested in our Pilot site. Here are the step we go thro.

  1. include vendor/plugin/action_mailer_tls
  2. create config/initializers/mail.rb
  3. use ActionMailer as normal

#vendor/plugins/action_mailer_tls/init.rb
require_dependency ’smtp_tls’

#vendor/plugins/action_mailer_tls/lib/smtp_tls.rb
require “openssl”
require “net/smtp”

Net::SMTP.class_eval do
private
def do_start(helodomain, user, secret, authtype)
raise IOError, ‘SMTP session already started’ if @started
check_auth_args user, secret, authtype if user or secret

sock = timeout(@open_timeout) { TCPSocket.open(@address, @port) }
@socket = Net::InternetMessageIO.new(sock)
@socket.read_timeout = 60 #@read_timeout
@socket.debug_output = STDERR #@debug_output

check_response(critical { recv_response() })
do_helo(helodomain)

raise ‘openssl library not installed’ unless defined?(OpenSSL)
starttls
ssl = OpenSSL::SSL::SSLSocket.new(sock)
ssl.sync_close = true
ssl.connect
@socket = Net::InternetMessageIO.new(ssl)
@socket.read_timeout = 60 #@read_timeout
@socket.debug_output = STDERR #@debug_output
do_helo(helodomain)

authenticate user, secret, authtype if user
@started = true
ensure
unless @started
# authentication failed, cancel connection.
@socket.close if not @started and @socket and not @socket.closed?
@socket = nil
end
end

def do_helo(helodomain)
begin
if @esmtp
ehlo helodomain
else
helo helodomain
end
rescue Net::ProtocolError
if @esmtp
@esmtp = false
@error_occured = false
retry
end
raise
end
end

def starttls
getok(’STARTTLS’)
end

def quit
begin
getok(’QUIT’)
rescue EOFError
end
end
end

# config/initializers/mail.rb
ActionMailer::Base.delivery_method = :smtp
ActionMailer::Base.smtp_settings = {
:address => “smtp.gmail.com”,
:port => 587,
:authentication => :plain,
:user_name => “username@your-domain.com”,
:password => “password”
}
One thing we need to be sure is to use a email user name without special char. We tried to use no-reply@xxx.com but it failed to login gmail auth system.

Ferret’s analyzer perform terribly support for multilingual .
thanks for the plugin multilingual_ferret_tools
Here is the description from it:

This plugin provides a multilingual-aware Analyzer for Ferret.  This analyzer is useful when
fields may contain characters from multiple languages.  Fields are broken into latin parts and
non-latin-parts- the latin parts are then processed with Ferret::Analysis::StandardAnalyzer, and
the non-latin parts are processed with Ferret::Analysis::RegExpAnalyzer.  By default, the RegExpAnalyzer
used considers each character as a distinct token.

If you want to change the configuration of the delegated analyzers, you'll find that initialization
code in MultilingualFerretTools::Analyzer#token_stream_for.

http://svn.lingr.com/plugins/multilingual_ferret_tools/

to install thru piston, simply execute below :

piston import http://svn.lingr.com/plugins/multilingual_ferret_tools/ vender/plugins/multilingual_ferret_tools

To enable ,add analyzer parameter to acts_as_ferret :

acts_as_ferret (
{:fields => {
:name                  => { :boost => 2 },
:chinese_name          => { :boost => 2 },
:self_description      => { :boost => 1.5 },
:subtitle              => {},
:teaching_time_remarks => {},
:description           => {},
:extra_curriculums     => {},
:job_description1      => {},
:job_description2      => {},
:primary_school        => {},
:secondary_school      => {},
:other_university      => {},
:university_major      => {},
:university_minors     => {},
:professional_courses  => {},
}},
{:analyzer => MultilingualFerretTools::Analyzer.new })

Related:

gem dependencies in 2.1.0

27 Jun 2008 In: Ruby On Rails

In Rails 2.1 we now have the ability to set gem dependencies.

to config, we can add config.gem in config/environment.rb

When I try to add

config.gem “RedCloth”

config.gem “mime-types”

it throw RedCloth and mime-types error .seems it cannot detect the gems library and always execute gem install .

no such file to load — RedCloth
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:27:in `gem_original_require’
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:27:in `require’
/usr/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:509:in `require’
/usr/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:354:in `new_constants_in’
/usr/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:509:in `require’
/usr/lib/ruby/gems/1.8/gems/rails-2.1.0/lib/rails/gem_dependency.rb:57:in `load’
/usr/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/core_ext/symbol.rb:11:in `__send__’
/usr/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/core_ext/symbol.rb:11:in `to_proc’
/usr/lib/ruby/gems/1.8/gems/rails-2.1.0/lib/initializer.rb:246:in `each’
/usr/lib/ruby/gems/1.8/gems/rails-2.1.0/lib/initializer.rb:246:in `load_gems’
/usr/lib/ruby/gems/1.8/gems/rails-2.1.0/lib/initializer.rb:137:in `process’
/usr/lib/ruby/gems/1.8/gems/rails-2.1.0/lib/initializer.rb:93:in `send’
/usr/lib/ruby/gems/1.8/gems/rails-2.1.0/lib/initializer.rb:93:in `run’
/root/apps/duncan_mod/config/environment.rb:13
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:27:in `gem_original_require’
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:27:in `require’
/usr/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:509:in `require’
/usr/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:354:in `new_constants_in’
/usr/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:509:in `require’
/usr/lib/ruby/gems/1.8/gems/rails-2.1.0/lib/tasks/misc.rake:3
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:546:in `call’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:546:in `execute’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:541:in `each’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:541:in `execute’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:508:in `invoke_with_call_chain’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:501:in `synchronize’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:501:in `invoke_with_call_chain’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:494:in `invoke’
/usr/lib/ruby/gems/1.8/gems/rails-2.1.0/lib/tasks/gems.rake:15
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:546:in `call’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:546:in `execute’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:541:in `each’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:541:in `execute’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:508:in `invoke_with_call_chain’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:501:in `synchronize’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:501:in `invoke_with_call_chain’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:518:in `invoke_prerequisites’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:1183:in `each’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:1183:in `send’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:1183:in `each’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:515:in `invoke_prerequisites’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:507:in `invoke_with_call_chain’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:501:in `synchronize’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:501:in `invoke_with_call_chain’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:494:in `invoke’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:1931:in `invoke_task’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:1909:in `top_level’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:1909:in `each’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:1909:in `top_level’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:1948:in `standard_exception_handling’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:1903:in `top_level’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:1881:in `run’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:1948:in `standard_exception_handling’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:1878:in `run’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/bin/rake:31
/usr/bin/rake:19:in `load’
/usr/bin/rake:19
no such file to load — mime-types
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:27:in `gem_original_require’
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:27:in `require’
/usr/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:509:in `require’
/usr/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:354:in `new_constants_in’
/usr/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:509:in `require’
/usr/lib/ruby/gems/1.8/gems/rails-2.1.0/lib/rails/gem_dependency.rb:57:in `load’
/usr/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/core_ext/symbol.rb:11:in `__send__’
/usr/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/core_ext/symbol.rb:11:in `to_proc’
/usr/lib/ruby/gems/1.8/gems/rails-2.1.0/lib/initializer.rb:246:in `each’
/usr/lib/ruby/gems/1.8/gems/rails-2.1.0/lib/initializer.rb:246:in `load_gems’
/usr/lib/ruby/gems/1.8/gems/rails-2.1.0/lib/initializer.rb:137:in `process’
/usr/lib/ruby/gems/1.8/gems/rails-2.1.0/lib/initializer.rb:93:in `send’
/usr/lib/ruby/gems/1.8/gems/rails-2.1.0/lib/initializer.rb:93:in `run’
/root/apps/duncan_mod/config/environment.rb:13
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:27:in `gem_original_require’
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:27:in `require’
/usr/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:509:in `require’
/usr/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:354:in `new_constants_in’
/usr/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:509:in `require’
/usr/lib/ruby/gems/1.8/gems/rails-2.1.0/lib/tasks/misc.rake:3
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:546:in `call’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:546:in `execute’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:541:in `each’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:541:in `execute’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:508:in `invoke_with_call_chain’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:501:in `synchronize’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:501:in `invoke_with_call_chain’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:494:in `invoke’
/usr/lib/ruby/gems/1.8/gems/rails-2.1.0/lib/tasks/gems.rake:15
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:546:in `call’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:546:in `execute’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:541:in `each’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:541:in `execute’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:508:in `invoke_with_call_chain’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:501:in `synchronize’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:501:in `invoke_with_call_chain’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:518:in `invoke_prerequisites’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:1183:in `each’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:1183:in `send’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:1183:in `each’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:515:in `invoke_prerequisites’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:507:in `invoke_with_call_chain’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:501:in `synchronize’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:501:in `invoke_with_call_chain’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:494:in `invoke’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:1931:in `invoke_task’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:1909:in `top_level’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:1909:in `each’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:1909:in `top_level’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:1948:in `standard_exception_handling’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:1903:in `top_level’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:1881:in `run’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:1948:in `standard_exception_handling’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:1878:in `run’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/bin/rake:31
/usr/bin/rake:19:in `load’
/usr/bin/rake:19
no such file to load — RedCloth
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:27:in `gem_original_require’
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:27:in `require’
/usr/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:509:in `require’
/usr/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:354:in `new_constants_in’
/usr/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:509:in `require’
/usr/lib/ruby/gems/1.8/gems/rails-2.1.0/lib/rails/gem_dependency.rb:57:in `load’
/usr/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/core_ext/symbol.rb:11:in `__send__’
/usr/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/core_ext/symbol.rb:11:in `to_proc’
/usr/lib/ruby/gems/1.8/gems/rails-2.1.0/lib/initializer.rb:246:in `each’
/usr/lib/ruby/gems/1.8/gems/rails-2.1.0/lib/initializer.rb:246:in `load_gems’
/usr/lib/ruby/gems/1.8/gems/rails-2.1.0/lib/initializer.rb:142:in `process’
/usr/lib/ruby/gems/1.8/gems/rails-2.1.0/lib/initializer.rb:93:in `send’
/usr/lib/ruby/gems/1.8/gems/rails-2.1.0/lib/initializer.rb:93:in `run’
/root/apps/duncan_mod/config/environment.rb:13
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:27:in `gem_original_require’
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:27:in `require’
/usr/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:509:in `require’
/usr/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:354:in `new_constants_in’
/usr/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:509:in `require’
/usr/lib/ruby/gems/1.8/gems/rails-2.1.0/lib/tasks/misc.rake:3
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:546:in `call’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:546:in `execute’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:541:in `each’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:541:in `execute’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:508:in `invoke_with_call_chain’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:501:in `synchronize’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:501:in `invoke_with_call_chain’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:494:in `invoke’
/usr/lib/ruby/gems/1.8/gems/rails-2.1.0/lib/tasks/gems.rake:15
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:546:in `call’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:546:in `execute’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:541:in `each’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:541:in `execute’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:508:in `invoke_with_call_chain’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:501:in `synchronize’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:501:in `invoke_with_call_chain’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:518:in `invoke_prerequisites’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:1183:in `each’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:1183:in `send’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:1183:in `each’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:515:in `invoke_prerequisites’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:507:in `invoke_with_call_chain’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:501:in `synchronize’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:501:in `invoke_with_call_chain’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:494:in `invoke’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:1931:in `invoke_task’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:1909:in `top_level’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:1909:in `each’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:1909:in `top_level’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:1948:in `standard_exception_handling’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:1903:in `top_level’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:1881:in `run’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:1948:in `standard_exception_handling’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:1878:in `run’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/bin/rake:31
/usr/bin/rake:19:in `load’
/usr/bin/rake:19
no such file to load — mime-types
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:27:in `gem_original_require’
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:27:in `require’
/usr/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:509:in `require’
/usr/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:354:in `new_constants_in’
/usr/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:509:in `require’
/usr/lib/ruby/gems/1.8/gems/rails-2.1.0/lib/rails/gem_dependency.rb:57:in `load’
/usr/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/core_ext/symbol.rb:11:in `__send__’
/usr/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/core_ext/symbol.rb:11:in `to_proc’
/usr/lib/ruby/gems/1.8/gems/rails-2.1.0/lib/initializer.rb:246:in `each’
/usr/lib/ruby/gems/1.8/gems/rails-2.1.0/lib/initializer.rb:246:in `load_gems’
/usr/lib/ruby/gems/1.8/gems/rails-2.1.0/lib/initializer.rb:142:in `process’
/usr/lib/ruby/gems/1.8/gems/rails-2.1.0/lib/initializer.rb:93:in `send’
/usr/lib/ruby/gems/1.8/gems/rails-2.1.0/lib/initializer.rb:93:in `run’
/root/apps/duncan_mod/config/environment.rb:13
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:27:in `gem_original_require’
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:27:in `require’
/usr/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:509:in `require’
/usr/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:354:in `new_constants_in’
/usr/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:509:in `require’
/usr/lib/ruby/gems/1.8/gems/rails-2.1.0/lib/tasks/misc.rake:3
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:546:in `call’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:546:in `execute’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:541:in `each’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:541:in `execute’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:508:in `invoke_with_call_chain’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:501:in `synchronize’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:501:in `invoke_with_call_chain’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:494:in `invoke’
/usr/lib/ruby/gems/1.8/gems/rails-2.1.0/lib/tasks/gems.rake:15
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:546:in `call’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:546:in `execute’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:541:in `each’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:541:in `execute’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:508:in `invoke_with_call_chain’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:501:in `synchronize’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:501:in `invoke_with_call_chain’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:518:in `invoke_prerequisites’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:1183:in `each’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:1183:in `send’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:1183:in `each’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:515:in `invoke_prerequisites’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:507:in `invoke_with_call_chain’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:501:in `synchronize’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:501:in `invoke_with_call_chain’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:494:in `invoke’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:1931:in `invoke_task’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:1909:in `top_level’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:1909:in `each’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:1909:in `top_level’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:1948:in `standard_exception_handling’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:1903:in `top_level’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:1881:in `run’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:1948:in `standard_exception_handling’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake.rb:1878:in `run’
/usr/lib/ruby/gems/1.8/gems/rake-0.8.1/bin/rake:31
/usr/bin/rake:19:in `load’
/usr/bin/rake:19
gem install RedCloth
Successfully installed RedCloth-3.0.4
1 gem installed
gem install mime-types
Successfully installed mime-types-1.15
1 gem installed
Installing ri documentation for mime-types-1.15…
Installing RDoc documentation for mime-types-1.15…

however it is not my intend.. after reading http://rails.lighthouseapp.com/projects/8994/tickets/293-gem-dependencies-broken-in-2-1-0 , I noticed that we have to include :lib in the config if the library name isn’t the same as the gems name .

config.gem “RedCloth” ,:lib => ‘redcloth’

config.gem “mime-types”, :lib => ‘mime/types’

Cool