1

前文:

私のRails 3アプリがhas_many_polymorphs gemを使用しているという事実に怖がらないでください。ここで私を助けるためにgemに精通する必要はないと思います:)

私のコード:

多くのスニペットを持つ Post モデルがあります。snippetable、つまりタイプSnippetの4 つの追加モデルがあります。

class Post < ActiveRecord::Base
  has_many_polymorphs :snippets, 
                      :from => [:texts, :videos, :images, :codes], 
                      :through => :snippets
end

class Snippet < ActiveRecord::Base
  belongs_to :post
  belongs_to :snippetable, :polymorphic => true      
  attr_accessible :post_id, :snippetable_type, :snippetable_id
end

# There following four models are snippetable:

class Code < ActiveRecord::Base
  # note that the attribute name is the same as the Class name
  attr_accessible :code
end

class Text < ActiveRecord::Base
  # note that the attribute name is the same as the Class name
  attr_accessible :text
end

class Image < ActiveRecord::Base
  # note that the attribute name is the same as the Class name
  attr_accessible :image
end

class Video < ActiveRecord::Base
  # note that the attribute name is the same as the Class name
  attr_accessible :video
end

投稿へのスニペットの追加

投稿に 2 つのテキスト スニペットと 2 つの画像スニペットを追加する場合は、次のようにします。

# find the first post
p = Post.first

p.texts << Text.create(:text => "This is the first sentence")
p.images << Image.create(:image => "first_image.jpg")
p.texts << Text.create(:text => "This is the second sentence")
p.images << Image.create(:image => "second_image.jpg")

結果は、次のようなブログ投稿です。

  • テキストスニペット
  • 画像スニペット
  • テキストスニペット
  • 画像スニペット

私の問題

ビューに各スニペットのコンテンツを表示するのに問題があります。

私の見解では、次のことができます。

- for text in @post.texts
  = text.text
- for image in @post.images
  = image.image
- for code in @post.codes
  = code.code
- for video in @post.videos
  = video.video

しかし、これは次のようなブログ投稿になります。

  • テキストスニペット
  • テキストスニペット
  • 画像スニペット
  • 画像スニペット

このようにスニペットがクラスごとにグループ化されることは望ましくありません。

どうすればこれを解決できますか?

さて、私は問題を見てきました。私は次のことができることを知っています

- for snippet in @post.snippets
  = snippet.snippetable_type.downcase

これにより、次のように各スニペットのクラス名が出力されます。

  • 文章
  • 画像
  • 文章
  • 画像

しかし、各スニペットのコンテンツが必要です。

上記の内容を拡張すると、各タイプのスニペットにはクラス自体と同じ名前の属性が 1 つあるため、次のようにすることもできます。

- for snippet in @post.snippets
  = "#{snippet.snippetable_type.downcase}.#{snippet.snippetable_type.downcase}"

これにより、各スニペットのクラス名と属性名が出力されます。

  • テキスト.テキスト
  • 画像.画像
  • テキスト.テキスト
  • 画像.画像

クラス名ではなくコンテンツに到達する方法を見つけることができれば、大丈夫です。誰でも手がかりを得ましたか?

誰かがこれを手に入れたら、私は絶対に驚かれることでしょう。ここまで読んでくれてありがとう。

4

2 に答える 2

3

あなたはあなたに与えられた順序でそれを望んでfor snippet in @post.snippetsいますが、に応じてテキスト、画像、コード、またはビデオを送信する必要がありますかsnippetable_type、それとも私はあなたを誤解していますか?

- for snippet in @post.snippets
  = snippet.snippetable.send(snippet.snippetable_type.downcase)
于 2010-12-15T23:43:35.667 に答える
1

(a) このアプリとこれらのスニペットが表示されているよりも複雑であるか、(b) オーバーヘッドが保証されない状況で has_many_polymorphs を使用しているかどうか疑問に思っています。

つまり、これらのスニペット タイプが、クラス名とアクセサ名を除いてまったく同じである場合、サブクラスはまったく必要ありません。汎用の Post クラスが 1 つあれば十分です。

一方、Post/Snippet クラスの動作がタイプによって異なる場合は、ダック タイピングを使用して必要な出力を取得することをお勧めします。(そして、あなたのコードからそれを理解すれば、これは実際には has_many_polymorphs の全体的な目的である可能性があります。)例:各スニペット可能なタイプは、メソッド(ダックタイプ) .to_html() を実装でき、それぞれが必要最小限の html を作成します。それに最も適したプレゼンテーション。そして、これはループ内で呼び出すメソッドです。

于 2010-12-16T02:02:05.120 に答える