ActiveRecordメモ その2

前回書いたので、メモをまたまた残しておく

今回は、以下の3つを書き起こす。

  • 既存行の更新処理
  • データ保存系メソッドの違い
  • 既存行の削除処理
  • コールバック

既存行の更新


1.更新する行を特定してから更新するやり方

1
2
3
table = Tables.find(12)
table.name = "column name"
table.save

2.属性の値を変更してからモデルオブジェクトを取得するやり方

1
2
table = Tables.find(12)
table.update_attribute(:name, "column_name")

上はシンボルを使って、特定の1カラムのみの更新の場合

まとめて行を更新する場合、ハッシュを使いますね。

1
2
table = Tables.find(12)
table.update_attributes(name: "column_name", text: "ActiveRecord")

因みに、Railsだとこんな感じで使ってますね。

1
2
3
4
5
6
7
8
def update
  table = Tables.find(params[:id])
  if table.update_attributes(params[:table])
    redirect_to action: :index
  else
    redirect_to action: :edit
  end
end

3.行の読み込みと更新を一度に行う方法

これは特に言うこともないですね。
指定した行を更新し、結果をDBに反映、そのままオブジェクトを取得します

1
table = Tables.update(12, name: "column_name", text: "ActiveRecord")

因みに、update_allメソッドを使えばまとめて更新することができます。
第1引数にupdate文、第2引数にwhere句を指定という形でやります。

1
table = Tbales.update_all("name = column_name, text = ActiveRecord", "id = 12")

戻り値は、データベースのアダプターによって異なるようです。
大体、更新行数が返るようですが、Oracleだけ何故か違うみたいです。。。

データ保存系メソッドの違い


メソッド 違い
save レコードが保存された場合、trueを返し、そうでなければnilを返す
save! 保存が成功した、trueを返し、そうでなければ例外を発生
create 保存に成功したかどうかは関係なく、ActiveRecordオブジェクトを返す。データが保存されたかどうかの確認は検証チェックが必要
create! 成功時は、ActiveRecordオブジェクトを返し、そうでなければ例外を発生

なので、使い分けはこんな感じに行う

1
2
3
4
5
if table.save
  検証と保存に成功
else
  検証エラー
end
1
2
3
4
5
6
7
begin
  table.save!
rescue ActiveRecord::RecordInvalid => error
  検証エラー
rescue ActiveRecord::RecordNotSaved => error
  保存に失敗(コールバックで保存が出来なかった)
end

既存行の削除処理


これは2種類の方法があります。
1つ目、データベースを直接操作する感じのやり方

こんな感じで、id指定で削除できます。
idを格納した配列を指定することで、まとめて削除もできます。

1
Tables.delete(12)

SQLのwhereを使ってまとめて削除する方法

1
Tables.delete_all(["id = 12"])

これもupdate_allメソッドと同じで削除した行数が返ってきます。

もう一つのやり方は、destroyメソッドを使う方法です。
こいつは、削除というよりもデータの凍結ですね。

特定の行のみ凍結

1
Tables.destroy(12)

まとめて凍結する方法

1
Tables.destroy_all("name = ?", "column_name")

因みにdeleteメソッドを使った場合、
ActiveRecordの検証メソッドが実行されないことに注意かも。

コールバック順序


コールバックで独自に処理を入れたい場合ってあると思うので、ついでにメモしておく

新規レコードでmodel.saveを実行した場合、以下の順序でコールバックされる

  1. before_validation
  2. 検証処理
  3. after_validation
  4. before_save
  5. before_create
  6. 挿入処理
  7. after_create
  8. after_save

更新の場合だと以下になる

  1. before_validation
  2. 検証処理
  3. after_validation
  4. before_save
  5. before_update
  6. 更新処理
  7. after_update
  8. after_save

削除(model.destroy)だと、以下になる

  1. before_destroy
  2. destroy処理
  3. after_destory

ここまでそれなりに書いたので、もうちょい参照系も書いておきたいなw