2012-03-04 11 views
2

私は特定のタイプの投稿でブログを作成しているとします。Railsでモデル継承を設定するにはどうしたらいいですか?私はクラスと2つのサブクラスを持っています

私はItemというモデルを持っています。 Itemには、名前や文字列などの名前(文字列)とリンク(文字列)があります。アイテムhas_and_belongs_to_many:tags(タグは、独自のデータベースに格納された文字列です)。

商品を2つの異なるモデルに拡張したいと考えています。引用とリンク。

見積もりは、コンテンツ(テキスト)が添付された商品です。

リンクはItemとほとんど同じです。

テキストとリンクの両方にアイテムクラスの名前とリンクが必要ですが、見積もりには余分なフィールド(コンテンツ:テキスト)があります。私はLinkにサブクラスを与えているに過ぎません。なぜなら、Quoteのスーパークラスと考えるべきではないからです。

自分のページにリンクとクォートを表示して別々に表示できるようにしたいと考えています。また、フロントページのすべてのアイテムをリストし、それらを別々にレンダリングできるようにしたいと考えています(引用はコンテンツを表示する必要があります)。

誰でも助けてもらえますか?

+1

ちょうど警告:ActiveRecordでの継承は、うっかりイライラする可能性があります。 –

+2

あまり抽象的な例が役に立ちません。 FooとBarをFrobにどうやって関連づけていますか?単一テーブルの継承を介して? –

+0

@MarcTalbot私はあまり抽象的ではなく、助けてくれることを望みました。 – Ali

答えて

2

これはActiveRecordの継承のかなり単純なケースで、STI(Single Table Inheritance)は必要なだけで十分です。

itemsテーブルには、それぞれの子孫属性をカバーするために必要なすべてのフィールドと、ActiveRecordによって内部的に使用されるタイプ(文字列)フィールドがすべて含まれていることを確認してください。各レコードのクラス。

この場合、データベースのitemsテーブルにコンテンツ(テキスト)フィールドとタイプ(文字列)フィールドを追加する必要があるようです。あなたが右のフィールドを持っていたら

、先に行くと、サブクラスItem

class Quote < Item 
    ... 
end 

などなど

私はあなたが両方のタイプの単一ItemsControllerを使用して、できるだけ多くの機能を維持するお勧めします親モデルは、一般的に物事をよりクリーンかつシンプルに保つためです。

サブビューごとにshow個のビューを独自のビューフォルダに追加します(app/views/linksなど)。そのため、それぞれのページで別々に表示することができます。

また、items#indexページでrender @itemを呼び出すと、Railsがインテリジェントにレンダリングするタイプごとにapp/views/links/_link部分を追加します。

# items/index.html.haml 
- @items.each do |item| 
    = render item 

上記 Quoteレコードを Linkレコードの app/views/links/_link.html.hamlapp/views/quotes/_quote.html.hamlをレンダリングします。

これは、説明する機能を簡単に実現するはずです。

+0

これはこれまでのところうまくいくようです! ItemsControllerから継承するためだけに存在するLinkとQuoteのコントローラを追加し、config/routes.rbのリソースとして2つのタイプを追加しました。私は、それぞれのフォームをレンダリングするために、ビューフォルダ固有のパーシャルを使用しています。 私は使用しました:私のモデル/ item.rbのすべての共通フィールドでattr_accessible、および:attr_accessible on:models/quote.rbのコンテンツ。ただし、新しい見積もりを作成しようとするとエラーが発生します。「保護された属性を大量に割り当てることはできません:コンテンツ」。任意のヒント? – Ali

+1

興味深い。あなたがやっていることはかなり正しいようですが、正直言って私は自分のアプリケーションの中で 'attr_accessible'には決して特定できません。私は常に、親クラスのサブクラスのいずれかに必要なすべての属性をリストします。それは少し怠け者だと感じますが、それが何らかの問題を引き起こす状況を考えることはできません。すべてを保存したことを再確認し、サーバーを再起動して、問題が解決するかどうかを確認します。もしそれが間違いなく機能していれば、私は親クラスに追加して移動します。 – Luke

関連する問題