6

次の構造を持つ 2 つのモデルがあります。

class Wallet < ActiveRecord::Base
  include ActiveModel::Validations
  has_one :credit_card
  accepts_nested_attributes_for :credit_card

  validates :credit_card, :presence => true
  validates_associated :credit_card
  ...
end

class CreditCard < ActiveRecord::Base
  include ActiveModel::Validations
  belongs_to :wallet

  validates :card_number, :presence => true
  validates :expiration_date, :presence => true
  ...
end

RSpec を使用してアプリケーションの機能をテストしていて、奇妙なことに気付きました。ネストされたモデル (nil card_number を持つなど) の検証基準を満たさない属性でハッシュを作成し、update_attributes呼び出しを実行しようとすると、無効な CreditCard がネストされた Wallet オブジェクトで返されるものモデル、および適切なエラー。これは正しい、予想される動作です。

同じ Hash を取得して run を実行するassign_attributessave( update_attributes が実行する必要があるのはこれだけですが、完全に nil のネストされたオブジェクトを持つ無効な Wallet オブジェクトが返されます。なぜですか?そして、ネストされたすべてのオブジェクトを更新するにはどうすればよいですか?保存せずに属性値とエラーをチェックしますか?

4

3 に答える 3

4

まず第一にinclude ActiveModel::Validations、付属しているので必要ありませんActiveRecord::Base

2番目-はい、内部的にupdate_attributes使用するため、基本的には期待どおりに機能するはずです。assign_attributes

attr_accessible, attr_protected,オプションがなく、with/without_protection適切なハッシュを作成していると思います

{'credit_card_attributes' => {'card_number' => ''}}

次に、レール内のある種のバグのように見えます。しかし、同時にチェックしたところ、問題なく動作しているようです。

その上で、オブジェクトをテストに保存せずに検証をチェックしたい場合は、実行するだけです

Wallet.new(hash_with_attributes).valid?

ネストされた credit_card とエラーを含む適切なウォレット オブジェクトを返す必要があります。

于 2013-04-15T12:34:17.510 に答える
2

私には、Strong Params (Rails 4 機能) がネストされた属性を削除している可能性があるように思えます。それらがないと検証が失敗するため、エラーが発生して編集ページにリダイレクトされ、クレジット カードの nested_attributes は nil になりました。

おそらくこれが役立つでしょう。https://stackoverflow.com/a/17532811/793330

また、save と update_attributes は同じものではありません。Save はオブジェクト全体を保存しますが、 update は渡した変更されたアイテムのみを変更します。わずかな違いですが、違いはありません。

于 2014-02-08T23:50:13.677 に答える
0

私が理解しているように、assign_attributes はセキュリティ チェックをスキップします。

Rails 3 では、= と assign_attributes に違いはありますか?

于 2013-04-13T02:54:58.090 に答える