Foobarの作成を担当する「クイック追加」フォームがあります。送信/保存すると、次の Foobar を追加するためにフォームに戻ります。作成中の Foobar に追加したいポリモーフィックタスクがあります。このコンテキストでは、タスクは詳細を必要としないため、フォームに「このタスクを実行する」というチェックボックスを表示することにしました。フォーム送信時にチェックが入っていれば、タスクを作成してFoobarに関連付けたいと思います。
それを行うのは難しくありませんが、「正しい」と思われる方法を見つけるのに苦労しています。
オプション 1: Foobar は、_nested_attributes_for Tasks を受け入れるので、ネストされたフォームを作成できますが、ネストするものは実際にはありません。チェックボックスは、タスクの有効なフィールドを表していません。タスクを作成したいだけです。@foobar.build_task を使用してタスクのフォームにいくつかの隠しフィールドを配置することもできますが、チェックボックスがチェックされていない場合にフィールドが送信されないようにするには、JS voodoo を使用する必要があります。これはただ汚いと間違っているようです。
オプション 2: FoobarController#create に、チェックボックスを探して、保存する前にタスクを Foobar にビルドするロジックを入れることができます。ここでの問題は、Task がポリモーフィックであり、他のものにも関連付けられる可能性があることです。作成される単一の Foobar に関連付けられた複数の「タイプ」のタスクさえある場合があります。このソリューションはオプション 1 よりも優れていると思いますが、あまり DRY ではありません。コントローラー内のそのようなロジックは、他のタスク可能なもののためにコントローラー内で複製されることになります。
オプション 3:「create_task」と呼ばれる疑似フィールドの存在を探してからタスクをビルドする before_save を Foobar に配置します。これにより、重複がコントローラーからタスク可能なモデルに移されますが、各モデルの「has_many :tasks」行が重複する以上の重複ではありません。とはいえ、そんなフィールドを探して行動するのがモデルの仕事ではないようです。
そう....いくつかの考えを本当に感謝します。
更新 #1: 少し追加情報...
タスクには作成者と担当者もあり、どちらもシステム内のユーザーです。作成者は current_user メソッドに基づいて自動的に割り当てられる必要があります。これはもちろんビューとコントローラーで使用できますが、モデルでは使用できません。答えが純粋にモデルベース(オプション3など)である可能性をすぐに除外すると思います。ユーザーは改ざんできないサーバー側に設定する必要があるため、回答がビューベースではないことも示唆していると思います(オプション1など)。では、答えはコントローラーのどこかにあるのではないでしょうか? おそらく、タスク可能なものを処理する各コントローラーで複製されるロジックをラップするためのヘルパーメソッドのようなものでしょうか?
更新 #2: 私の現在の傾向は...
私は、尊敬されている開発者の友人と時間をかけて話しましたが、その答えがオプション 2 に最も近いとさらに確信しています。ビューとモデルの両方が間違っているようです。コントローラーは理にかなっていますが、主な問題はコードが繰り返される可能性です。答えは、コントローラーが担当するオブジェクトへのタスク (またはコメント、ファイルのアップロードなどの他のポリモーフィックなもの) の添付を処理するコントローラー コードを除外する最善の方法を見つけることにあると思います。満足のいく解決策が得られたら、ここに投稿してみます。ご意見ありがとうございます。