我在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访问它?所以基本上,我试图从子对象访问父类的属性。
答案 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关系一样。