Active Record 3.1系コマンド

はじめに_

Active Record (Rails) 3.1系のコマンド覚書。基本的にデータベースから値を取り出すコマンドのメモ。 2.3系のコマンドとは大幅に変わったので注意。

参考文献・リンク_

返り値_

コマンド成功したとき 失敗したとき
User.find(id) レコード例外 RecordNotFound
User.firstレコードnil
User.lastレコードnil
User.allレコード空の配列
他のコマンドActiveRecord::RelationActiveRecord::Relation

デバッグ方法_

ActiveRecord::Relationはto_sqlでSQL文として出力可能なのでそれでチェックする。

relation = User.where("user_name = ? AND password = ?", user_name, password)
logger.debug("SQL is #{relation.to_sql}."

コマンド例_

id から検索する場合_

  • User.find(id) :id一つ
  • User.find(配列) :複数のid

あるフィールドの要素に関して一致するものを探す場合_

  • User_find_by_フィールド名('文字列')
  • User_find_by_フィールド1_and_フィールド2('文字列1', '文字列2')

存在するならそのレコードを返し、存在しないなら新しいレコードを作成する_

TagsテーブルのnameフィールドがSummerであるレコードがあれば、そのレコードを返し、そうでなければnameフィールドにSummerを代入した新たなレコードを作成する。

  • Tag.find_or_create_by_name("Summer")

存在するならそのレコードを返し、存在しないなら新たなオブジェクトを作成する_

TagsテーブルのnameフィールドがWinterであるレコードがあれば、そのレコードを返し、そうでなければnameフィールドにWinterを代入した新たなオブジェクトを作成する。

  • Tag.find_or_initialize_by_name("Winter")

条件検索:SQLのwhere_

Active Record 3.0以降、whereの返り値はリレーションというクラスであり、オブジェクト配列として確定させたい場合は、allやfirstを追加する必要がある。

  • SQL
    SELECT * FROM users WHERE user_name = "USER_NAME AND" password = "PASSWORD";
    SELECT * FROM users WHERE user_name = "USER_NAME AND" password = "PASSWORD" LIMIT 1;
    
  • 2.3系
    User.find(:all, :conditions => ["user_name = ? AND password = ?", user_name, password])
    User.find(:first, :conditions => ["user_name = ? AND password = ?", user_name, password])
    
  • 3.1系:3つの表現は違うが生成されるSQL文は同じ。
    User.where("user_name = ? AND password = ?", user_name, password).all
    User.where(:user_name => user_name, :password => password).all
    User.where("user_name = ?", user_name).where("password = ?", password).all
    
    User.where("user_name = ? AND password = ?", user_name, password).first
    User.where(:user_name => user_name, :password => password).first
    User.where("user_name = ?", user_name).where("password = ?", password).first
    

条件+BETWEEN_

SQLのBETWEENを使う場合。以下の場合gradeフィールドで9から12の値が格納されているものを探す。

Student.where(:grade => 9..12)

条件+IN_

SQLのINを使う場合。以下の場合gradeフィールドで9, 11, 12の値が格納されているものを探す。

Student.where(:grade => [9,11,12])

並び順を指定する:SQLのorder_

  • ASC:昇順(小→大。デフォルト)
  • DESC:降順(大→小)
  • SQL
    SELECT * FROM users ORDERD BY id;
    SELECT * FROM users WHERE id < "NUMBER" ORDERD BY id DESC;
    
  • 2.3系
    User.find(:all, :order => "id")
    User.find(:all, :conditions => ["id < ?", number], :order => "id DESC")
    
  • 3.1系
    User.order("id").all
    User.where("id < ?", number).order("id DESC")
    

グループ化: SQLのgroup_

  • 3.1系
    User.group("name")
    

表の結合:SQLのINNER JOIN_

INNER JOINについての説明は以下のページを参照のこと。

関連モデルの一括読み出し earger loading_

AuthorとBookが1対多の関係となっているとき、あるAuthorに関連づけられているBookをまとめて効率良く呼び出すときに includeを用いる。 joinとの違いは、joinは複数の表を結合して読み出すときに使うのに対し、 includeは earger loadingを実現するために使う。

  • 3.1系
    User.where("user_name = ? AND password = ?", user_name, password).includes(:blog).all