AWDwR "Chapter14 Active Record Basics"
いよいよActive Recordですよ。
テーブルとクラス
DHHの趣味でテーブル名はモデルのクラス名の複数形と仮定しているけど、嫌な場合は
ActiveRecord::Base.pluralize_table_name=false
とすればモデルのクラス名とテーブル名を一緒にできる。また自分でテーブル名を指定したい場合は
class Sheep < ActiveRecord::Base set_table_name "sheep" end
というような感じでOK。
SQLのdecimal型はRubyのfloat型にマップされるので注意。またbooleanの属性は0と1で格納されるので以下の点に注意。
if user.superuser × 常にtrueと判定されてしまう if user.superuser? ○ こうしましょう
プライマリキーとID
デフォルトではidという名前のintegerのカラムをプライマリキーとするんだけど、他のカラムをプライマリキーにしたい場合は以下のようにする。その場合プライマリキーの値は自分で設定しなければいけないので注意。
class BadBook < ActiveRecord::Base set_primary_key :isbn end
データベースへの接続
データベースへの接続の設定はestablish_connectionメソッドでできるけど、普通は設定ファイルのdatabase.ymlでしましょう。
CRUD
レコードの作成
新しく作成するレコードの初期化方法
Order.new do |o| o.name = "enkimi" o.save end order = Order.new( :name => "enkimi" ) oreder.save
createメソッドを使えばダイレクトにDBに書き込んでくれる。saveメソッド不要。
order = Order.create( :name => "enkimi" )
レコードの読み込み
こんな感じ。
Order.find(1) Order.find([1,3,5,7,9]) Order.find(:all, :conditions => ["name=? and pay_type=?", name, pay_type]) Order.find(:all, :conditions => ["name=:name and pay_type=:pay_type", params]) Order.find(:all, :order => "id", :limit => page_size, :offset => page_number*page_size) Order.find_by_sql("select * from orders") Order.count Order.count(["name=?", name])
ダイナミックファインダはおもしろい。
Order.find_by_name(name) Order.find_all_by_name(name) User.find_by_name_and_password(name, password)
レコードの更新
こんな感じ。
Order.update_attribute(:name, "enkimi") Order.update_attributes(:name => "enkimi", :email => "enkimi@foo.com") Order.update(12, :name => "enkimi") Order.update_all("price=1.1*price", "title like '%Java'")
save()は保存できた場合はtrue、保存に失敗した場合はfalseを返す。一方save!()は保存に失敗した場合はRecordInvalid例外を上げる。
楽観的ロック
楽観的ロックを使用したい場合はテーブルにlock_versionという名前のintegerのカラムを作りましょう。初期値は0とすること。
レコードの削除
こんな感じ。
Order.delete(1) Order.delete([1,2,3,4,5]) Order.delete_all(["price < ?", price)
インスタンスメソッドのdestroy()はそのインスタンスに該当するDBのレコードを削除し、そのインスタンスを変更不可にする。一方クラスメソッドのdestroy(),destroy_all()はDBからレコードを読み込んでインスタンスを生成しインスタンスメソッドのdestroy()を呼び出す。destroy()はdelete()と違ってコールバックやバリデーションを実行する。普通はdestroyを使いましょう。
続きはまた。