これには非常に遅れましたが、2p/2c を追加すると思いました。
私は、リクエスト タイプとパラメーターに基づいてプログラム フロー コードとして大まかに定義するコントローラー コード以外は、コントローラーをクリーンな状態に保つようにしています。たとえば、リクエスト タイプに適したテンプレートを選択したり、ユーザーがログインしているかどうかに基づいて呼び出す正しいメソッドを選択したりします。
応答の計算に関しては、モデルを操作してインスタンス パラメーターを設定する大量のコードをコントローラーに散らかすのは好きではありません。これはテストが難しく、再利用するのはさらに困難です。別のオブジェクトを延期し、単一の値オブジェクトをテンプレートに返すことを好みます。
場合によっては、モデルに従うこともできます。単純なルックアップで、単一のモデルまたはモデルの配列をテンプレートに送信しているだけかもしれません。
適切な値または値オブジェクトを返すために、モデルに便利なメソッドを実装した可能性があります。
ただし、モデルを使用しないことや、複数のモデルを使用すること、または実際にモデルを散らかすべきではないと感じることがあります。この場合、コントローラもモデルもコードの適切な場所ではありません。
lib ディレクトリも適切ではありません。私は lib ディレクトリを、まだ gem に変換したことがないコードを含む場所として扱う傾向があります。私が書いているコードがアプリケーションのコンテキストでしか意味をなさない場合、それはうまくいきません。
そこで、サービス オブジェクトに目を向けます。「app」フォルダーの下に「services」フォルダーがあります。このフォルダーには、サイトの動作の単一のチャンクをカプセル化する小さな機能クラスが含まれています。(または、コントローラーに単純なインターフェースを提供するために、他のいくつかのサービスを調整することもあります。)
これにより、コントローラーとモデルをスリム化でき、API に接続する必要があるコードを配置するのに最適な場所になります。
さらに一歩進めたい場合は、API 自体をラッパー クラス (またはクラスのセット) でラップし、それらを lib ディレクトリに保持することができます (後で gem に変換するため)。次に、サービス オブジェクトは、(コントローラーから渡された) 適切な値で API ラッパーを呼び出すタスクを実行し、テンプレートがクリーンに問い合わせることができる何かで応答します。
もちろん、これをさらに進めて、さらにレイヤーを追加することもできます。たとえば、プレゼンテーション レイヤーは、サービス オブジェクト (一般的な値を提供する) と特定のビューのフォーマット データの間に配置できます。(たとえば、Web ページと RSS フィードの両方を提供する必要があり、それらには異なる日付形式が必要な場合があります。)
しかし、あなたはその考えを理解します。