2013-05-19 47 views
0

我有一个需要做一个查询记录集,并获得许多类型的对象列表。正确的协会设计

在这个例子中,我将使用博客文章,其中有许多不同类型的博客文章。

基地邮编:

class Post < ActiveRecord::Base 
    belongs_to :postable, :polymorphic => true 
    attr_accessible :body, :title 
end 

音频后期:

class AudioPost < ActiveRecord::Base 
    attr_accessible :sound 
    has_one :postable, :as => :postable 
end 

图文帖子:

class GraphicPost < ActiveRecord::Base 
    attr_accessible :image 
    has_one :postable, :as => :postable 
end 

这会让我做这样的事情。

@post = Post.all 
@post.each do |post| 
    post.title 
    post.body 
    post.postable.image if post.postable_type == "GraphicPost" 
    post.postable.sound if post.postable_type == "AudioPost" 
end 

虽然这个工作,但检查类型,因为这是违反鸭式原则,感觉不对。我会认为有更好的办法可以做同样的事情。

什么是更好的设计来实现这个相同的目标还是我只是在想我的设计?

+1

继承更适合我在这种情况下,你为什么要选择多态关联? – juanpastas

+0

我想你知道STI,'AudioPost juanpastas

+0

欢迎来到Rails城市的限制。如果你走得更远,你可能会发现自己哼唱Sinatra先生的曲调。 – 2013-05-19 20:25:26

回答

2

查看我的评论。

无论如何,如果你想多态的,我会写逻辑模型:

class Post 
    delegate :content, to: :postable 


class AudioPost 
    alias_method :sound, :content 


class GraphicPost 
    alias_method :image, :content 

您将要呈现不同的图像比声音,对于这部分,我会用一个帮手:

module MediaHelper 
    def medium(data) 
    case # make your case detecting data type 
    # you could print data.class to see if you can discriminate with that. 

,并查看呼叫

= medium post.content 
+0

这看起来像它会工作,虽然我不是100%出售,如果我应该使用多态来实现这一点。主要是你的展示的原因。你显示的是更多的鸭子类型,它也不太透明你最终使用一个条件来正确渲染。我并不是指责你,只是想看看还有哪些其他选择。 你可能会同意,这可能是最好的多形性,它可能不是最好的所有设计选择。 –