不要被My Rails 3应用程序使用has_many_polymorphs gem吓到,因为我不认为您需要熟悉gem以帮助我:)
我有一个Post模型,它有很多Snippets。还有四个其他模型可剪切,即类型 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
现在,如果我想在帖子中添加两个文本片段和两个图片片段,我可以这样做:
# 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
但是这将导致博客文章如下所示:
我不希望以这种方式按类对片段进行分组。
好吧,我看看这个问题。我知道我 CAN 执行以下操作:
- for snippet in @post.snippets
= snippet.snippetable_type.downcase
这将输出每个代码段的类名称,如下所示:
但我想要每个片段的内容。
扩展我们上面的内容,因为每种类型的代码段都有一个与Class本身同名的属性,我也可以这样做:
- for snippet in @post.snippets
= "#{snippet.snippetable_type.downcase}.#{snippet.snippetable_type.downcase}"
这将输出每个代码段的类名和属性名称:
如果我能找到一种获取内容而不是类名的方法,那么我会好的。有人有任何线索吗?
如果有人得到这个,我会非常惊讶。如果你已经读过这篇文章,那就谢谢了。
答案 0 :(得分:3)
所以你想按for snippet in @post.snippets
给你的顺序想要它,但你需要根据snippetable_type
发送文字,图片,代码或视频,还是我误读了你?
- for snippet in @post.snippets
= snippet.snippetable.send(snippet.snippetable_type.downcase)
答案 1 :(得分:1)
我想知道是否(a)这个应用程序和这些片段的复杂程度比你所展示的要多,或者(b)你在不保证开销的情况下使用has_many_polymorphs。
我的意思是:如果这些片段类型除了类名和访问者名称之外确实完全相同,那么根本不需要子类:一个通用的Post类就可以了。
另一方面,如果Post / Snippet类根据类型确实有不同的行为,那么更好的解决方案是使用duck typing来获得所需的输出。 (如果我从你的代码中理解它,这实际上可能是has_many_polymorphs的全部目的。)例如:每个snippetable类型都可以实现一个方法(duck类型).to_html(),其中每个都会创建一个简单的html演示文稿最适合它。然后这个就是你在循环中调用的方法。