简体   繁体   English

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

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM