Monday, September 27, 2010

Ruby code snippets

1. using 'any?' to check if something in a array/hash
# a = User.all
a.any? {|user| user.name == "Hoang"}

Thursday, September 23, 2010

Some ways to refactoring Rails' code

On the following, I list some ways I found to refactoring my Rails' code. This list would be added more as time's going.

1. Method delegation
    Assume you have two models:
       + User(id, name)
       + Account(id, number, user_id)
    It could be described in Rails as:

       class User < ActiveRecord::Base
         has_many :accounts
       end
       class Account < ActiveRecord::Base
         belongs_to :user
       end

    Then if I have an Account instance named account, I could get it's user's name by: account.user.name or I can define an instance method in Account as follow:

       class Account < ActiveRecord::Base
         belongs_to :user
         
         def user_name
           user.name
         end
       end  
    Then you can get account's user name by: account.user_name. We can make the above code shorter by using delegation:

       class Account < ActiveRecord::Base
         belongs_to :user
         delegate :name, :to => :user, :prefix => true   ## this will generate user_name methods 
       end  

2. Use define_method to dynamically generate similar methods
    Given a model User(id, name, role) where role could be "admin", "moderator", "senior", "junior",... You can write instance methods to see whether a user is "admin", "moderator", ... as follow:

Before
class User < ActiveRecord::Base
  ROLES = {
    :admin => "admin",  
    :moderator => "moderator",
    :senior => "senior",
    :junior => "junior"}

    def admin?
      role == ROLES[:admin]
    end
        
    def moderator?
      role == ROLES[:moderator]
    end

    def senior?
      role == ROLES[:senior]
    end
        
    def junior?
      role == ROLES[:junior]
    end          
end
After
class User < ActiveRecord::Base
  ROLES = {
    :admin => "admin",     
    :moderator => "moderator", 
    :senior => "senior", 
    :junior => "junior"} 

    ROLES.each_pair do |key, val| 
      define_method(key.to_s + "?") { role == val}
    end
end