2012-10-06 52 views
0

我有以下模型結構。 我有一個行程有許多行程節點。每個行程節點都是圍繞地點,旅館,活動等的包裝。Mongoid has_one多態關聯

行程= 「巴黎之行」 Itinerary.itinerary_nodes = [節點1,節點2,節點3],其中 節點1 = 「JFK機場」 節點2 = 「戴高樂機場」 節點3 = 「埃菲爾鐵塔」

所以本質上節點代表你將在你的行程中訪問的地方。在我的模型結構中;讓我們假設我的機場與紀念碑或酒店不同。現在我想創建一個關聯,

class ItineraryNode 
    include Mongoid::Document 
    has_one :stopover 
end 

其中每個中途停留可以是不同的對象。它的類型和id是默認存儲的,後來使用它來誇大。

那麼我該如何聲明與ItineraryMode關聯的多個模型?我可以通過確保在初始化程序中手動設置這些屬性來實現此目的;但是好奇的是,如果像這樣的東西是默認支持的。

乾杯

回答

4

這不是一個 「HAS_ONE」,這是一個 「belongs_to的」(多態)

class ItineraryNode 
    include Mongoid::Document 
    belongs_to :stopover, :polymorphic => true 
    belongs_to :itinerary 
end 

class Airport 
    include Mongoid::Document 
    has_many :itinerary_nodes, :as => :stopover 
end 

class Place 
    include Mongoid::Document 
    has_many :itinerary_nodes, :as => :stopover 
end 

所以現在你可以得到:

@itinerary.itinerary_nodes.each do |node| 
    if node.stopover.is_a? Airport 
    puts "Welcome to #{note.stopover.name}" 
    elsif node.stopover.is_a? Event 
    puts "Bienvenue, would you like a drink?" 
    elsif node.stepover.is_a? Place 
    puts "The ticket line is over there" 
    end 
end 

(我用了一個if構造只是爲了更好地展示多態性,您可以在這裏使用case構造...)

你會發現node.stepover可以有很多類。

編輯(評論後,我明白ItineraryNode模式是一種嘗試手工製作的多態性的許多-to-many關聯

從Mongoid文檔:

Polymorhic除了has_and_belongs_to_many之外,所有關係都允許行爲

因此,您需要使用中間模型(ItineraryNode)。提供的解決方案是我能想到的最簡單的解決方案。

+0

我的意圖是讓行程有很多節點;一個節點繞過中途停留。我理解你給出的表示;但我不想在行程中說行程有多少個機場; has_many地方等我想說的行程has_many節點。然後節點可以抽象出潛在的地方。 所以我希望Node能夠說has_one:某種東西,然後東西可以是機場或地點或任何東西。 我不認爲有可能從上面顯示的內容中實現這一點。 – Priyank

+1

重點在於「has_one」意味着另一側的「belongs_to」。你不想讓機場屬於一個節點(它只屬於**節點**)。所以你想要的是節點**屬於某種東西,並且東西可以是任何需要的東西(即多態性)。我會編輯回覆更清晰。 – rewritten

+0

非常好!現在很清楚。感謝您盡全力詳細解釋它。我明白你的意思了。乾杯。 – Priyank