[英]Reverse Polymorphic Association in Rails (Accessing the parent's attributes)
I implemented an example of Reverse Polymorphism in Rails with the selected answer from this question: Reverse Polymorphic Associations 我用以下问题的选定答案实现了Rails中的反向多态性的示例: 反向多态性关联
With this we are able to do the following: 有了这个,我们可以做到以下几点:
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">]
I'm wondering if it's possible to modify this such that if I do t.article_elements
that I can also see the attributes for the picture to. 我想知道是否可以修改它,以便在执行
t.article_elements
也可以看到图片的属性。 So for example, if I had an picture_name attribute for the variable p, how can I access that from t.article_elements ? 因此,例如,如果我具有变量p的picture_name属性,如何从t.article_elements访问该属性? So basically, I am trying to access the parent's attributes from the child object.
所以基本上,我试图从子对象访问父对象的属性。
Note that t.article_elements
is a collection. 请注意,
t.article_elements
是一个集合。 I will use article_element
to refer to one member of the collection. 我将使用
article_element
来引用集合的一个成员。
Per your example, 根据您的示例,
article_element.element.picture_name
will work. 将工作。
However, you run into a problem with undefined methods by mismatched attributes. 但是,由于属性不匹配,您遇到了未定义方法的问题。 For example, a video would not have a
picture_name
attribute. 例如,视频将没有
picture_name
属性。 If all element types shared a common attribute, such as name
, it would be fine. 如果所有元素类型都共享一个公共属性,例如
name
,那就很好了。
One way to avoid this problem is to check whether the element responds to a given attribute method. 避免此问题的一种方法是检查元素是否响应给定的属性方法。 For example:
例如:
# models/article_element.rb
def element_try(method)
self.element.respond_to?(method) ? self.element.send(method) : ""
end
If our element is a video and we call: 如果我们的元素是视频,我们调用:
article_element.element_try(:picture_name) # => ""
we will get a blank string instead of NoMethodError
. 我们将获得一个空白字符串而不是
NoMethodError
。
This solution is a bit hacky, so use at your own risk. 该解决方案有点笨拙,因此使用后果自负。 Personally, I'd use common attributes instead.
就个人而言,我将改用通用属性。
I had similar situation. 我也有类似情况。
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
When you wanna access parent of image, you can do Image.last.imageable
and that will give you either User or Person object. 当您想访问图像的父对象时,可以执行
Image.last.imageable
,这将为您提供User或Person对象。 It works same with has_many relations. 与has_many关系相同。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.