[ANN] rails_best_practices 0.7.1 released

flyerhzm Posted by flyerhzm on February 24, 2011


I just released rails_best_practices 0.7.1, the changes in 0.7.1 are as follows:

1. read the source codes as encoding utf-8, fix issue https://github.com/flyerhzm/rails_best_practices/issues#issue/36

2. add --with-mvim option which adds link url to the filenames in rails_best_practices html output, binging you to mvim who will open that file with that line number.

Check it here: https://github.com/flyerhzm/rails_best_practices.

Migrate from authlogic/authlogic-connect to devise/omniauth

flyerhzm Posted by flyerhzm on February 24, 2011


At the beginning of building rails-bestpractices.com, I chose authlogic as the authentication gem, as I'm familiar with authlogic that time. Then I chose authlogic-connect to make website support sign in with Twitter and Facebook. They work fine except that I will receive error emails, said

undefined method `visit_ResponseString' for #<Arel::Visitors::MySQL:0xc58314c>
arel (2.0.3) lib/arel/visitors/visitor.rb:15:in `visit'

when someone signed in with Twitter or Facebook. It happened occasionally, but it made me crazy as it didn't occur when I signed in with Twitter or Facebook.

One week before I decide to use devise and omniauth to replace the current authentication system, devise is the most popular authentication gem for rails3 application, omniauth is used for authentication with third party websites, like Twitter and Facebook.

authlogic => devise

The most important thing is that you should have good test coverage before you start to migrate from authlogic to devise.

1. After writing tests, you can remove authlogic gem and add devise gem in Gemfile

# gem "authlogic"
gem "devise"

2. Next you should change the table users' columns

class MigrateUsers < ActiveRecord::Migration
  def self.up
    add_column :users, :reset_password_token, :string
    add_column :users, :remember_token, :string
    add_column :users, :remember_created_at, :datetime
    add_column :users, :authentication_token, :string

    rename_column :users, :crypted_password, :encrypted_password

    remove_column :users, :persistence_token
    remove_column :users, :single_access_token
    remove_column :users, :perishable_token

  def self.down
    add_column :users, :perishable_token, :string
    add_column :users, :single_access_token, :string
    add_column :users, :persistence_token, :string

    rename_column :users, :encrypted_password, :crypted_password

    remove_column :users, :authentication_token
    remove_column :users, :remember_created_at
    remove_column :users, :remember_token
    remove_column :users, :reset_password_token

As you seen, devise and authlogic use different column names for users table, you should add/remove/change columns for your own projects.

3. Then remove the authlogic related codes, and generate the devise codes according to the devise documents.

4. Finally, you should change the configuration in config/initializers/devise.rb

config.stretches = 20
config.encryptor = :authlogic_sha512

it tells devise to use the same password encryption algorithm with authlogic. So the existed users can sign in with their account/password.

Now you can sign up / sign in for a new user with devise, and of course sign in with old users.

authlogic-connect => omniauth

The another thing to consider is old users who are signed in with Twitter and Facebook.

1. remove authlogic-connect gem and add omniauth gem in Gemfile

# gem "authlogic-connect"
gem "omniauth", "0.2.0.beta4"

I use omniauth 0.2.0.beta4 as it provides an easy way for integrate test.

2. I added the omniauth feature according to railscasts' episodes OmniAuth Part 1 and  OmniAuth Part 2.

3. Don't forget to migrate old twitter/facebook token and secret to the new table, the following script is what I did for such migration.

FacebookToken.all.each { |facebook|
  facebook.key = facebook.token.split("|")[1].split("-")[1]

AccessToken.all.each { |access_token|
  Authentication.create(:provider => access_token.type.sub("Token", "").downcase, :uid => access_token.key, :user_id => access_token.user_id, :token => access_token.token, :secret => access_token.secret, :created_at => access_token.created_at, :updated_at => access_token.updated_at)

AccessToken is old model with authlogic-connect and Authentication is the new model with omniauth. It just copied data from one table to another.


Please Check out the source codes here: https://github.com/flyerhzm/rails-bestpractices.com. You will see more, such as implementation details of devise and omniauth and cucumber tests for authentication.

Everything works fine in rails-bestpractices.com now, enjoy the new implementation of authentication.

[ANN] rails_best_practices 0.7.0 released

flyerhzm Posted by flyerhzm on February 15, 2011


I just released rails_best_practices 0.7.0, the changes in 0.7.0 are as follows:

1. add rubygems-test support.

2. add remove trailing whitespace check.

3. add use multipart/alternative as content_type of email check.

4. do not check needless deep nesting for shallow routes.

Check it here: https://github.com/flyerhzm/rails_best_practices

[ANN] rails_best_practices 0.6.7 released

flyerhzm Posted by flyerhzm on February 14, 2011


I just released rails_best_practices 0.6.7, it also does a lot of refactorings. The changes in 0.6.7 are as follows:

1. all ###_check.rb files are renamed to ###_review.rb, and ###Check classes are renamed to ###Review.

2. prepare process and review process are isolated, they are separated into Prepare module and Review module.

3. prepare process is executed before checking all reviews.

4. use rspec's let and have(n) syntax for better tests.

Check it here: https://github.com/flyerhzm/rails_best_practices

Test your rubygem under different rubies

flyerhzm Posted by flyerhzm on January 26, 2011


When I build the rails_best_practices gem and other rubygems, I always face the issues that some methods work in ruby 1.8.7, but failed in ruby 1.9.2, or some work in ruby 1.9.2, but failed in ree. As Ruby has been developing a long time, some api interfaces have been removed and some have been added, that means some api interfaces between ruby 1.9.2 and ruby 1.8.7 are not compatible, the same to ruby 1.8.7 and ruby 1.8.6. In addition, there are a lot of variants, such as ree, rubinius, jruby, macruby and etc. How should we promise our rubygems can work fine under these different rubies?

Let's thank RVM again. It makes testing much easier under different rubies. I wrote two scripts for rails_best_practices gem, one is install_supported_rubies.sh which install all the rubies that you want your rubygems to support.

rubies=( 1.8.7 1.9.2 ree )

for x in ${rubies[*]}
  rvm install $x
  rvm $x && rvm gemset use global && gem install bundler

It's a simple shell script, install ruby 1.8.7, 1.9.2 and ree, and install the bundler for all of the rubies. It should be only executed when the rubies you are not installed.

The other is rake_rubies.sh which runs the tests under different rubies.

rubies=( 1.8.7 1.9.2 ree )

for x in ${rubies[*]}
  rvm use --create $x@$gemset
  bundle install
  rake spec

It will use or create a gemset rails_best_practices for all rubies, install all dependent rubygems, and then run the rspec tests. I always run this script to check if rails_best_practices gem works fine under different rubies.