2017-08-11 71 views
0

想象一下你有一個旅行網站HotelOwner s和Tourist s。當他們開始對話時,該應用使用has_many through創建一個名爲Conversation的加入模型。這是一個典型的多對多關聯:Rails`belongs_to``通過has_one低谷其中加入模型has_many的子模型

class HotelOwner 
    has_many :tourists, through: :conversations 
    has_many :conversations 
end 

class Tourist 
    has_many :hotel_owners, through: :conversations 
    has_many :conversations 
end 

class Conversation 
    belongs_to :hotel_owner 
    belongs_to :tourist 
end 

現在我們可以使用hotel_owner.touriststourist.hotel_owners。此外,加入模型Conversation也被用於保持它們之間的關聯狀態(例如,HotelOwner評論Tourist,反之亦然)。

但是現在我們需要預訂模型。我最初的IDEIA是這樣的:

class Reservation 
    belongs_to :hotel_owner 
    belongs_to :tourist 
end 

但是,我們還需要創建Conversation加盟模式,因爲應用程序邏輯要求,即使一個空白的存在不能成爲Reservation沒有以前Conversation。另外,hotel_owner關於遊客的筆記應該保留在那裏,如果有預訂,則需要存在。

考慮使用人工回調手動創建的連接模式Conversation後,我讀了它不會對Reservation添加belongs_to :conversation一個好主意,因爲它可能導致數據庫不一致(如問題,如果reservation.conversation.tourist指着不同的旅遊則reservation.tourist ..應該有真理的單一來源,以該協會右)

然後我不得不使用Conversation作爲代理預訂,這樣的想法:

class HotelOwner 
    has_many :tourists, through: :conversations 
    has_many :conversations 
    has_many :reservations, through: :conversations 
end 

class Tourist 
    has_many :hotel_owners, through: :conversations 
    has_many :conversations 
    has_many :reservations, through: :conversations 
end 

class Conversation 
    belongs_to :hotel_owner 
    belongs_to :tourist 
    has_many :reservations 
end 

class Reservation 
    has_one :hotel_owner, through: :conversation 
    has_one :tourist,  through: :conversation 
    belongs_to :conversation 
end 

由於Rails中沒有belongs_to through用於Reservation,所以SO中的其他帖子建議使用has_one trough來代替,就像我上面所做的那樣。

的問題是,談話的has_many保留,並且不belong_to預約(像它不屬於TouristHotelOwner)。

這不僅是語義,打擾我。如果我做的是hotel_owner.reservations.create(tourist: Tourist.last),它確實創建了保留,但未建立連接模型Conversation,而是留下reservation.conversation零。

經過簡單的hotel_owner.reload,返回零。

什麼是正確的數據庫設計和Rails關聯模型?

回答

0

你可以把它簡單的是這樣的:

class HotelOwner < ActiveRecord::Base 
    has_many :reservations 
    has_many :conversations 
end 

class Tourist < ActiveRecord::Base 
    has_many :reservations 
end 

# hotel_owner_id, tourist_id 
class Reservation < ActiveRecord::Base 
    belongs_to :tourist 
    belongs_to :hotel_owner 

    has_one :conversation, dependent: :destroy 
    after_create { self.conversation.create! } 
end 

# reservation_id 
class Conversation < ActiveRecord::Base 
    belongs_to :reservation 
end 

然後,您可以通過以下方式訪問這些協會:

# get all reservations and conversations for a hotel_owner 
HotelOwner.last.reservations 
HotelOwner.last.conversations 

# all reservations made by a tourist 
Tourist.last.reservations 

# conversation associated to a reservation 
Reservation.last.conversation 

# get reservation, hotel_owner and tourist from a conversation 
Conversation.last.reservation 
Conversation.last.reservation.tourist 
Conversation.last.reservation.hotel_owner 
相關問題