0

UserモデルとStripeCustomerモデルがあります。すべてのユーザーが1つ埋め込み、StripeCustomerのaccepts_nested_attributes_for。

新しいユーザーを作成するとき、私は常に対応するStripeCustomerを作成し、CCまたはクーポンコードのいずれかを提供する場合は、サブスクリプションを作成します。

私のStripeCustomerで:

attr_accessible :coupon_id, :stripe_card_token

クーポンが無効な場合は、次のようにします。

errors.add :coupon_id, "bad coupon id"

そのため、通常のレールコントローラは次のようにパターン化されます。

if @stripe_customer.save
    ....
else
    ....
end

うまくいくでしょう。そして、悪いクーポンを処理するために通常のレールfield_with_errorsのものを使用することができます。

したがって、問題は、どのアクティブレコードコールバックでStripe :: Customer.createを呼び出し、stripe_customer_tokenを保存する必要があるかということです。

あなたが本当にレコードを永続化しようとしている場合にのみそれを実行したいので、私はbefore_createにそれを持っていました。しかし、これは有効な奇妙なことをしますか?さらに悪いことに、Userを介して作成する場合は、before_createコールバックでerrors.addを実行しても、UserとStripeCustomerの保存は実際に成功します。問題は、エラーを追加してbefore_validationでfalseを返した場合にのみ、保存が失敗することだと思います。

その最後の部分は、それがモンゴイドの問題であるかどうかはわかりません。

before_validation:on =>:createに移動できますが、有効と呼んだ場合でも、新しいStripe :: Customerが作成されますか?欲しくない。

とにかく、リモートサービスのレコードにバックアップまたはリンクされているモデルのベストプラクティスと、エラーの処理方法について一般的に興味があります。

4

2 に答える 2

1

これが私が行ったことです。ストライプの呼び出しを2つのコールバックに分割します。1つはbefore_validationで、もう1つはbefore_create(またはbefore_update)です。

before_validationでは、制御されていない入力(ユーザーから直接)が有効であることを確認するためにできることは何でもします。単にクーポンコードを意味するストライプの場合、それが有効であることをストライプで確認し、必要に応じて:coupon_codeにエラーを追加します。

実際にストライプを使用して顧客を作成/更新する場合は、before_create / before_updateまで待ちます(これら2つのケースの処理方法が異なるため、before_saveを実行する代わりに2つを使用します)。エラーが発生した場合は、検証後にエラーを追加しようとする代わりに、例外を処理しません。これは、(a)あまり意味がなく、(b)ある種の動作をしますが、ネストされたモデルでの保存を防ぐことができません。 (とにかくモンゴイドで、それは非常に悪くて奇妙です)。

このようにして、私が永続化するまでに、すべての属性が健全であることを知っています。もちろん、何かが失敗する可能性はありますが、リスクを大幅に最小限に抑えました。今、私は有効な呼び出しのようなこともできますか?ストライプでレコードを作成することを心配せずに、私は望んでいませんでした。

振り返ってみると、これはかなり明白に思えます。

于 2012-07-09T17:03:43.473 に答える
0

シナリオを完全に理解できるかどうかはわかりません。あなたが書いた:

すべてのユーザーが1つ埋め込み、StripeUserのaccepts_nested_attributes_for

StripeCustomerのことですか?

では、クーポン情報を保持している顧客を持つユーザーがいますか?

もしそうなら、ユーザーの顧客のネストされた属性を受け入れ、顧客コードに検証を入れれば十分だと思います。それだけです。こちらをご覧ください

あなたの質問が間違っていたら教えてください...

于 2012-07-07T05:47:44.790 に答える