1

我用这个问题的选定答案在 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 访问它?所以基本上,我试图从子对象访问父对象的属性。

4

2 回答 2

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.

这个解决方案有点hacky,所以使用风险自负。就个人而言,我会改用通用属性。

于 2013-01-20T11:38:14.433 回答
-1

我有类似的情况。

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 关系相同。

于 2013-11-20T20:00:45.913 回答