複数のレコードを同時にレールに追加したい。複数のレコードをレールに保存し、失敗した場合は元に戻す
tax_rates.map {|tax_rate| TaxRate.new(tax_rate).save }
しかし、これによっては一部のレコードが保存され、一部は拒否される可能性があります。
レコードの一部が失敗した場合、すべてのレコードを拒否する方法を誰に教えてもらえますか?
ありがとうございます。
複数のレコードを同時にレールに追加したい。複数のレコードをレールに保存し、失敗した場合は元に戻す
tax_rates.map {|tax_rate| TaxRate.new(tax_rate).save }
しかし、これによっては一部のレコードが保存され、一部は拒否される可能性があります。
レコードの一部が失敗した場合、すべてのレコードを拒否する方法を誰に教えてもらえますか?
ありがとうございます。
私はこのような何かをするだろう:
TaxRate.transaction do
tax_rates.map do |tax_rate|
raise ActiveRecord::Rollback unless TaxRate.new(tax_rate).save
end
end
またはあなたのモデルに新しいメソッドを追加したい場合があります読みやすさの理由のために:
# in models/tax_rate.rb
def self.create_all(rates)
transaction do
rates.map do |rate|
raise ActiveRecord::Rollback unless TaxRate.new(rate).save
end
end
end
そして、あなたのコントローラで使用このように:
TaxRate.create_all(tax_rates)
また、単に 'create!'や 'save!'を使ってください。 –
コントローラでトランザクションを使用できますか? – Avinash142857
@ Avinash142857はい。 – jemonsanto
トランザクションを使用します。
ActiveRecord::Base.transaction do
model1.create!
model2.create!
model3.create!
anything that triggers an exception
or raise ActiveRecord::Rollback
end
[1] pry(main)> ActiveRecord::Base.transaction do [1] pry(main)* User.create(email: "[email protected]", password: "asdkfasdlfk") [1] pry(main)* Network.create(user_id: 1) [1] pry(main)* end
(22.9ms) SET NAMES utf8, @@SESSION.sql_mode = CONCAT(CONCAT(@@sql_mode, ',STRICT_ALL_TABLES'), ',NO_AUTO_VALUE_ON_ZERO'), @@SESSION.sql_auto_is_null = 0, @@SESSION.wait_timeout = 2147483 (6.4ms) BEGIN User Exists (24.3ms) SELECT 1 AS one FROM `users` WHERE `users`.`email` = BINARY '[email protected]' LIMIT 1 (0.2ms) ROLLBACK ActiveModel::UnknownAttributeError: unknown attribute 'user_id' for Network.
トランザクションはロールバックを経由して、レコードの状態をリセットします。 Railsでは、ロールバックは例外によってのみトリガされます。 したがって、使用しているメソッドがをトリガーしていることを確認してください。 http://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html
EDIT:それは黙ってDBには何もコミットしていないことを証明するために、コードを追加し、いくつかのAR法は、このに関する詳細情報については、障害例えばupdate_attribute
上の例外をトリガしません。
問題は、特定の例が例外を発生させ、トランザクション全体を必要に応じて取り消しますが、トランザクションのブロックが例外を発生しない場合、ロールバックは発生しません。したがって、検証のために 'create'呼び出しの1つが失敗した場合、その失敗は暗黙のうちに無視されます。代わりに 'create!'を使用した場合、検証の問題から例外が発生し、トランザクションは必要に応じて機能します。データベースエラー(検証ではカバーしていないテーブル制約に違反するなど)によって例外が発生し、トランザクションは必要に応じて機能します。 –
@muistooshortトランザクションをロールバックするには、常にActiveRecord :: Rollbackを呼び出す機会があります。 – mudasobwa
[ o ask "](https://stackoverflow.com/help/how-to-ask)をクリックしてください。 – mudasobwa