2009-03-31 11 views
8

私は、3つのモデル、Person、Place、Thingを持つレールアプリを持っていると言います。 Thingが単一のテーブル継承を使用しているので、FancyThingサブクラスとScaryThingサブクラスがあるとします。次に、map.resources :people, :places, :thingsで定義されたルートがあります。したがって、FancyThingsとScaryThingsのコントローラーはなく、ThingsControllerはどちらのタイプも処理します。RailsのSTIクラスの基本クラスのルートを取得

は今、私は何のリストは、それらへのリンクを持って示したコードを持っている必要がありますと言います。私は私の見解では、このコードをお持ちの場合:

<% @items.each do |item| %> 
    <%= link_to item.name, item %> 
<% end %> 

項目が人や場所であれば、これは正常に動作し、polymorphic_pathは正しいルートを生成するの面倒を見ます。しかし、アイテムがFancyThingかScaryThingなら、これは吹き飛ばされます。fancy_thing_pathを使用しようとします。これにはルートはありません。どういうわけかthing_pathを使ってみたいです。理想的には、Thingおよび/またはそのサブクラスに、ルートを生成するためにサブクラスが基本クラスを使用する必要があることを示すメソッドがあります。これに優雅な解決策はありますか?

map.resources:物事:has_manyの=>

+0

これはレールの開発に[オープンチケット](http://dev.rubyonrails.org/ticket/10454)です。それに対処する方法の提案については、チケットを参照してください。 – MarkusQ

答えて

12

これは、トリックを行います:

<% @items.map {|i| if i.class < Thing then i.becomes(Thing) else i end}.each do |item| %> 
    <%= link_to item.name, item %> 
<% end %> 

これは、ActiveRecordの機能を使用して行うには、「なり」 Thing基本クラスに対するThingのすべてのサブクラスの「アップキャスト」。

+0

ニース、私は約、おかげで分からなかった! – pjb3

+0

このソリューションは、私が期待していたほどエレガントな約10倍です。 –

8

して正しい答えを持っていないが、少なくとも私は、非DRYコードを使用してこの問題に対処することができます

map.resources :things 
map.resources :fancy_things, :controller => 'things' 
map.resources :scary_things, :controller => 'things' 
+1

+1 2つの理由のために1)これは私のために働く。 2)この回答は、@ pjb3で受け入れたものよりも乾燥しているように見えます。ありがとう。 – Rohit

+0

このソリューションは機能しますが、クラス/タイプを強制しないという欠点があります。 http:// localhost:3000/fancy_things/21経由でIDを照会し、その項目が実際に別のサブクラスのScaryThingsにある場合でも、有効な応答が得られます。 FancyThingsクラスではないので、実際にはエラーが発生するはずです。 – Tilo

0

を使用してみてください:fancy_things、::コントローラ=> 'もの': map.resourcesを詰め込むにhas_many =>:scary_things、::コントローラ=> 'もの':has_manyのは=>:

はホープ詰め map.resourcesを詰め込みます問題は私が見たいと思っているのですぐに縁で修正されるでしょうfancy_thingsは以下によって管理します:物事コントローラー。これらのルートを使用して、あなたのようなURLで終了します:/ fancy_things/1あなたは多分したいのに対し、/物事/ 1

関連する問題