2011-01-14 22 views
19

ActiveRecordにはupsert機能が組み込まれていますか?私はそれを自分で書くことができると知っていますが、もしそのようなことが既に存在するなら、私は明らかにしたくありません。Upsert in Rails ActiveRecord

答えて

13

Model.find_or_initializeあなたがしたいことはありそうです。それが理にかなっている場合はsaveまたはupdate_attributesでチェーンすることができます。

詳細情報はRails Guidesです。私はちょうどこのライブラリに出会っ

+3

パスタの回答を参照してください – tybro0103

+1

これを見た人は誰ですか?レールガイドは、新しいオブジェクトがDBにまだ格納されていないことを示しているので、これが真のDBアップセートであるかどうかわかりません。すなわち、マルチスレッド環境では、確実に動作しません。 – stuckj

+2

このソリューションには並行性の問題があります。 'find_or_initialize'と' save'の間で別のスレッドがテーブルを更新すると失敗します。 –

3

もありModel.find_or_createさ: https://github.com/seamusabshere/upsert

私はまだそれをテストしていませんが、それは有望に見える

私は上のブログの記事を書いていた
+6

これはアップアップを行いません。これは、選択した後に(オプションで)挿入を行います。シングルスレッドの世界では同じ効果が得られますが、マルチスレッドの世界では実際のアップサルトを行う必要があります。 – tybro0103

-1

どのようにこれを達成できるか。それをチェックしてくださいhere

アクティブなレコード拡張機能を作成する必要があります。それはこのようなものに見えます。

​​
+3

特に、このエラーがいつ発生するかを予測できるときに、予想される論理フローを駆動するためにエラーを使用するファンではありません。 – kmanzana

+0

良い点@kmanzana。私にとってはちょっとハッキリしすぎる。私見では – olleh

0

IMO Upsertメカニズムでは、モデルごとにカスタム構成が必要です。

したがって、モデルのカスタムSQLクエリを実装するのが最善の解決策です。

insert into <table> (<field_1>, ..., <field_n>) 
    values (<field_1_value>, ..., <field_n_value>) 
on duplicate key update 
    field_x = field_x_value, 
    ... 
    field_z = field_z_value;