Rails中的反向多态关联(访问父级的属性)

时间:2013-01-20 05:56:40

标签: ruby-on-rails polymorphic-associations

我在Rails中实现了反向多态性的一个例子,并从这个问题中选择了答案: Reverse Polymorphic Associations

有了这个,我们可以做到以下几点:

t = Article.new
t.article_elements  # []
p = Picture.new
t.article_elements.create(:element => p)
t.article_elements  # [<ArticleElement id: 1, article_id: 1, element_id: 1, element_type: "Picture", created_at: "2011-09-26 18:26:45", updated_at: "2011-09-26 18:26:45">]
t.pictures # [#<Picture id: 1, created_at: "2011-09-26 18:26:45", updated_at: "2011-09-26 18:26:45">]

我想知道是否可以修改这个,如果我这样做的话 t.article_elements我还可以看到图片的属性。例如,如果我有变量p的picture_name属性,我如何从t.article_elements访问它?所以基本上,我试图从子对象访问父类的属性。

2 个答案:

答案 0 :(得分:1)

请注意t.article_elements是一个集合。我将使用article_element来引用该集合的一个成员。

根据你的例子,

article_element.element.picture_name 

会奏效。

但是,由于属性不匹配,您遇到了未定义方法的问题。例如,视频没有picture_name属性。如果所有元素类型共享一个公共属性,例如name,那就没问题了。

避免此问题的一种方法是检查元素是否响应给定的属性方法。例如:

# models/article_element.rb
def element_try(method)
  self.element.respond_to?(method) ? self.element.send(method) : ""
end

如果我们的元素是视频,我们会调用:

article_element.element_try(:picture_name) # => ""

我们将获得一个空白字符串而不是NoMethodError

此解决方案有点笨拙,因此请自担风险。就个人而言,我改为使用共同属性。

答案 1 :(得分:-2)

我有类似的情况。

class User < ActiveRecord::Base
    has_one :image, as: :imageable
end
class Person < ActiveRecord::Base
    has_one :image, as: :imageable
end
class Image < ActiveRecord::Base
    belongs_to :imageable, :polymorphic => true
end

如果您想访问图像的父级,可以执行Image.last.imageable,这将为您提供User或Person对象。它与has_many关系一样。