2013-01-20 55 views
2

我實現反向多態性的一個例子的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

請注意,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一個空字符串。

這個解決方案有點怪異,所以使用需要您自擔風險。就我個人而言,我會使用通用屬性。

+0

感謝您的回答。我想這可能工作。我也認爲你可以做t.article_elements.map {| x | x.element}#這遍歷每個article_element並返回其關聯的父模型及其所有屬性 –

+0

特定名稱問題的另一個解決方案是使用類似下面的內容:article_element.element.send(「#{element_type} _name」 )。但是。只有當名稱隨着類型名稱而變化時。 –

-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,並且會給你用戶或Person對象。它和has_many關係一樣。