Rails のビューとコントローラーにはredirect_to
、 、link_to
、およびform_for
メソッド呼び出しが散らばっています。とは、リンクしているパスで明示的であることもlink_to
ありますが (例: )、多くの場合、パスは暗黙的です (例: )。redirect_to
link_to 'New Person', new_person_path
link_to 'Show', person
モデルにいくつかの単一テーブル継承 (STI) を追加すると (たとえばEmployee < Person
)、これらのメソッドはすべてサブクラスのインスタンスに対して壊れます (たとえばEmployee
)。rails を実行するlink_to @person
と、 でエラーが発生しundefined method employee_path' for #<#<Class:0x000001022bcd40>:0x0000010226d038>
ます。Rails は、employee であるオブジェクトのクラス名によって定義されたルートを探しています。これらの従業員ルートは定義されておらず、従業員コントローラーがないため、アクションも定義されていません。
この質問は以前に尋ねられました:
- StackOverflowでの答えは、コードベース全体で link_to などのすべてのインスタンスを編集し、パスを明示的に記述することです
- 再びStackOverflow
routes.rb
で、サブクラスのリソースを親クラスにマップするために使用することを2人が提案しています (map.resources :employees, :controller => 'people'
)。同じSOの質問の一番の答えは、コードベース内のすべてのインスタンスオブジェクトを型キャストすることを提案しています.becomes
- StackOverflowでのさらに別の回答では、一番の答えは Do Repeat Yourself キャンプの方法であり、すべてのサブクラスに複製の足場を作成することを提案しています。
- ここでも同じ質問が SO にあり、一番上の答えが間違っているようです (Rails マジック Just Works!)。
- Web の他の場所で、F2Andy がコード内のあらゆる場所でパスを編集することを推奨しているこのブログ投稿を見つけました。
- ブログ記事「Single Table Inheritance and RESTful Routes at Logical Reality Design」では、上記の SO の回答 2 のように、サブクラスのリソースをスーパークラス コントローラーにマップすることをお勧めします。
- Alex Reisner は、Single Table Inheritance in Railsの記事を投稿しています。その中で彼は、子クラスのリソースを親クラスにマップすることに反対することを提唱してい
routes.rb
ます。そのため、代わりに、親クラスにメソッドを追加して、サブクラスがそのクラスについて嘘をつくようにすることをお勧めします。良さそうですが、彼の方法ではエラーが発生しました。link_to
redirect_to
form_for
undefined local variable or method `child' for #
したがって、最もエレガントに見え、最もコンセンサスが得られる答えは (ただし、それほどエレガントではなく、コンセンサスもそれほど多くありません)、リソースを に追加することroutes.rb
です。ただし、これは では機能しませんform_for
。私はいくつかの明確さが必要です!上記の選択肢を要約すると、私のオプションは次のとおりです。
- サブクラスのリソースをスーパークラスのコントローラーにマップします
routes.rb
(サブクラスで form_for を呼び出す必要がないことを願っています) - Rails の内部メソッドをオーバーライドして、クラスを相互に関連付けます。
- オブジェクトのアクションへのパスが暗黙的または明示的に呼び出されるコード内のすべてのインスタンスを編集し、パスを変更するか、オブジェクトを型キャストします。
これらすべての相反する答えがあるので、裁定が必要です。良い答えはないように思えます。これはレールの設計に失敗していますか? もしそうなら、それは修正されるかもしれないバグですか?または、そうでない場合は、誰かがこれについて私をまっすぐに設定し、各オプションの長所と短所を説明して(またはそれがオプションではない理由を説明して)、正しい答えとその理由を教えてくれることを願っています. それとも、ウェブ上で見つけられない正しい答えはありますか?