Schienen: Der Versuch, den Inhalt eines Objekts ausgegeben, wenn Sie nicht wissen, was Klasse das Objekt gehört zu
-
10-10-2019 - |
Frage
Präambel:
Sie werden durch die Tatsache Meine Rails 3 App nutzt die has_many_polymorphs gem wie ich don nicht verschreckt ‚t glaube, Sie müssen mit dem Edelsteine, um Hilfe vertraut sein, um mich hier:)
Mein Code:
Ich habe einen Beitrag Modell, das viele Snippets hat. Es gibt vier weitere Modelle, die sind snippetable das heißt vom Typ Snippet :
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
Schnipsel einen Beitrag
HinzufügenWenn ich nun zwei Textausschnitte und zwei Bildschnipsel zu einem Beitrag hinzufügen möchte ich dies tun können:
# 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")
Das Ergebnis ist ein Blog-Post, dass sieht wie folgt aus:
- Textausschnitt
- image Schnipsel
- Textausschnitt
- image Schnipsel
Mein Problem
Ich bin einige Probleme, den Inhalt jeder Schnipsel in meiner Ansicht angezeigt wird.
I könnte Sie wie folgt meiner Ansicht nach:
- 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
ABER diese in einem Blog-Eintrag führen, dass wie folgt aussieht:
- Textausschnitt
- Textausschnitt
- image Schnipsel
- image Schnipsel
Ich mag nicht, Schnipsel von Klasse auf diese Weise gruppiert werden.
Wie kann ich dieses Problem lösen?
Nun, ich habe einen Blick auf das Problem. Ich weiß, dass ich CAN Sie wie folgt vor:
- for snippet in @post.snippets
= snippet.snippetable_type.downcase
und dieser Wille Ausgang der Klassenname eines jeden Schnipsel wie folgt:
- text
- Bild
- text
- Bild
, aber ich möchte den Inhalt der einzelnen Schnipsel.
Die Erweiterung auf dem, was wir oben haben, da jede Art von Code-Schnipsel hat ein Attribut mit dem gleichen Namen wie die Klasse selbst, ich kann das auch tun:
- for snippet in @post.snippets
= "#{snippet.snippetable_type.downcase}.#{snippet.snippetable_type.downcase}"
Und dieser Wille Ausgang der Klassenname und das Attribut Name jedes Snippet:
- text.text
- image.image
- text.text
- image.image
Wenn ich nur einen Weg, um auf den Inhalt und nicht die Klassennamen finden könnte, dann würde ich in Ordnung sein. Jeder bekam eine Ahnung?
ich absolut erstaunt sein, wenn jemand diese bekommt man. Dank, wenn Sie bis hierher gelesen haben.
Lösung
So Sie es in der gewünschten Reihenfolge, dass for snippet in @post.snippets
gibt Ihnen, aber Sie müssen es sich um Text, Bild, Code oder Video senden je nach snippetable_type
, oder ich bin Verlesen Sie?
- for snippet in @post.snippets
= snippet.snippetable.send(snippet.snippetable_type.downcase)
Andere Tipps
Ich frage mich, wenn entweder (a) es zu diesen App mehr Komplexität ist und dieser Schnipsel als Sie zeigen, oder (b) Sie verwenden has_many_polymorphs in einer Situation, die nicht den Aufwand rechtfertigt.
Was ich meine ist: wenn diese Schnipsel Typen wirklich alle identisch, außer für die Klassennamen und Accessor Namen, dann müssen Sie nicht über die Unterklassen überhaupt. Eine allgemeine Beitrag Klasse tun
Auf der anderen Seite, wenn die Pfosten- / Snippet Klassen tun unterschiedliches Verhalten haben je nach Typ, dann eine bessere Lösung wäre Ente eingeben zu verwenden, um die Ausgabe, die Sie erhalten möchten. (Und das kann eigentlich der ganze Zweck der has_many_polymorphs sein, wenn ich es aus dem Code zu verstehen.) Zum Beispiel: Jeder snippetable Typ ein Verfahren implementieren könnte (die Ente Typ) .to_html (), in dem jedes ein nackten Knochen schaffen würde html Präsentation am besten geeignet, um es. Und dann das ist die Methode, die Sie in Ihrer Schleife nennen würden.