1

「複数のコントローラーアクション」を処理するRailsの方法は何ですか? 私のアプリケーションには、いくつかのモデルに影響を与える特別な「ショッピング カート」フローがあります。基本的に、フローはログインしている特別な種類のユーザーが利用でき、次のようになります。

  1. ユーザーを追加します。
    • ここで「ユーザーの追加」が可能です。Basecamp について知っている場合、この手順はプロジェクトに人を追加するのと少し似ています。したがって、このステップでは、ユーザー リソースの観点から考えています。
  2. ここでは、以前に追加したユーザーごとに「購入」することができます。
    • これは、基本的なショッピング カートのようなものです。ということで、リソース的には「ショップ」か「カート」を考えています。
  3. これは確認手順です。繰り返しますが、これはカートの一部だと思います。

確認後、いくつかのことが起こるはずです。

  1. 手順 1 で追加したユーザーは、何らかの方法でアクティブ化する必要があります。つまり、アクティブ化する前にログインすることはできません。
  2. ステップ 2 の買いから注文を出す必要があります。
  3. ステップ 2 で購入する「もの」は、ある種の仮想製品です。つまり、ユーザーがログインすると、製品は「招待状」として表示されます。これの詳細はあまり重要ではなく、説明するのが少し難しいです。重要な点は、確認後、データベースに招待状を作成し、ユーザーに関連付ける必要があるということです。

繰り返しになりますが、システムの詳細を説明するのは少し難しいのですが、主な質問は、この種のものを Rails で実装するのに最適な方法です。In にはいくつかの手順が含まれ、すべての手順で複数のモデルに影響を与えます。

ある種のステートマシンでそれを行うことを考えていました。ステートマシンは、ステップまたは状態間の遷移を担当し、必要なアクションを実行します。だから私はStateMachineControllerか、モデルなしでメインロジックを実装する何かを持っていると思います。これは操作するものですか?Rails は RESTfull リソースにかなり偏っているようですが、上記のような RESTfull アプローチを思いつかないようです。ありがとう。

4

1 に答える 1

1

コントローラーのアクションは、ユーザーが引き起こすイベントと考えてください。その後に起こるのは、通常 1 つ以上のモデルに関連付けられるべきロジックです。

したがって、注文は Order モデルに属し、ユーザーのアクティブ化は User モデルに属し、招待状の送信は Invitation モデルに属します。モデル同士がお互いのことを知っていても問題はありません。イベントが複数のモデルにまたがる場合、ユーザーが引き起こすイベントに最も密接に関連するメソッドにメソッドを配置します。おそらく Order の「purchase」のようなメソッドで、Order コントローラーから呼び出すメソッドです。

したがって、他のモデルの状態に依存関係がある場合はactivated?、ユーザーのように (必要に応じて) テストするための小さなメソッドを作成し、(ユーザーの状態を更新する) などの作業を行う他のモデルを作成activateし、招待で「招待」します。ユーザーに関連付けられた新しい招待を保存します。失敗した場合は、必ず例外を発生させてください。

細かい粒度の良いメソッドがたくさんできたら、それらをまとめて、Order#purchaseメソッド内のトランザクションにラップすることもできます。何かのようなもの

def purchase(user, stuff, invitee)
  Order.transaction do
    begin
      invitee.activate
      invitation = Invitation.create! {:invitee => invitee, :stuff => stuff, :invited_by => user }
      # You can't roll back an email, so do this after the others have worked without exception
      invitation.send
    rescue
      ActiveRecord::Rollback
    end
  end
end

すべてをトランザクションで行うことにより、データはすべて正しいか、そうでないかのどちらかになります。

そのような何か?

于 2012-11-16T22:51:43.653 に答える