Skip to content

DRY: Metaprogramming

Richard Huang edited this page Aug 15, 2010 · 3 revisions

Please go to http://rails-bestpractices.com/posts/16-dry-metaprogramming

Before:


class Post < ActiveRecord::Base

  validate_inclusion_of :status, :in => ['draft', 'published', 'spam']

  def self.all_draft
    find(:all, :conditions => { :status => 'draft' }
  end

  def self.all_published
    find(:all, :conditions => { :status => 'published' }
  end

  def self.all_spam
    find(:all, :conditions => { :status => 'spam' }
  end

  def draft?
    self.status == 'draft'
  end

  def published?
    self.status == 'published'
  end

  def spam?
    self.status == 'spam'
  end

end

After:


class Post < ActiveRecord::Base

  STATUSES = ['draft', 'published', 'spam']
  validate_inclusion_of :status, :in => STATUSES

  class <<self
    STATUSES.each do |status_name|
      define_method "all_#{status_name}" do
        find(:all, :conditions => { :status => status_name }
      end
    end

    STATUSES.each do |status_name|
      define_method "#{status_name}?" do
         self.status == status_name
      end
    end
  end
end