クラスのメソッド

クラスメソッドとインスタンスメソッドがわかっているようで、いつの間にかあやふやになってしまうので後で迷わないように整理しておく。

インスタンスメソッド

class User < ActiveRecord::Base
  def not_using_openid?
    identity_url.blank?
  end
end
User.new.not_using_openid?    # => OK
User.not_using_openid?        # => NG

インスタンス(User.new)を作ってからでないと使えないメソッド。デフォルトはこっち。インスタンスで使うので、当然のことながら、このメソッドの中にクラスメソッドを入れてはならない。

class User < ActiveRecord::Base
  def find_ip(id)
    find(:first, :select=>"ip", :conditions=>["id=?", id])
  end
end

findはクラスメソッドなので、こういう風にすると『undefined method `find'』エラーになる。

クラスメソッド

class User < ActiveRecord::Base
  def self.find_ip(id)
    find(:first, :select=>"ip", :conditions=>["id=?", id])
  end
end

クラス(User)で直接使えるメソッド。頭に selfを付ける。(クラス名を付けるとか、<< で定義するとかいろいろあるけど割愛)。インスタンスから使おうとすると『undefined method 'find_ip'』エラーになる。

User.find_ip(1)        # => OK
User.new.find_ip(1)    # => NG

クラス変数で受けるとか、こういう(↓)やり方でインスタンスのメンバーを返すのはあり。

  def self.find_ip(id)
    find(:first, :select=>"ip", :conditions=>["id=?", id]).ip
  end

named_scope

named_scopeはクラスメソッド。

class User < ActiveRecord::Base
  named_scope :find_ip, lambda {|id| {:select => "ip", :limit => 1, :conditions => ["id=?", id]}}
end
class User < ActiveRecord::Base
  def self.find_ip(id)
    find(:first, :select=>"ip", :conditions=>["id=?", id])
  end
end

これとこれは等価。