Ask A Question

Notifications

You’re not receiving notifications from this thread.

Trying to emulate `belongs_to trough` using `has_one trough` but having problems?.

iosman001 asked in General

Hello,

Imagine a travel website where you have HotelOwners and Tourists. When they start a conversation, the app creates a join model named Conversation using has_many through. It's a classic many to many association:

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

class Tourist
has_many :hotel_owners, through: :conversations
has_many :conversations
end
https://ometv.onl
https://chatroulette.onl
https://chatavenue.vip
class Conversation
belongs_to :hotel_owner
belongs_to :tourist
end
Now we can use hotel_owner.tourists and tourist.hotel_owners. Also, the join model Conversation is also being used to keep some state on that association between them both (like, HotelOwner comments on Tourist and vice-versa).

But now we need a Reservation model. My initial ideia was this:

class Reservation
belongs_to :hotel_owner
belongs_to :tourist
end
But we also need to create the Conversation join model, since app logic requires that there cannot be a Reservation without a previous Conversation, even if a blank one. Also, the hotel_owner notes on tourist and vice-versa should be kept there and need to exist if a reservation exists.

After thinking about using manual callbacks to manually create the join model Conversation, I read that it would not be a good idea to add a belongs_to :conversation on Reservation because it could lead to database inconsistencies (like the problem if reservation.conversation.tourist pointed to a different tourist then reservation.tourist .. there should be a single source of truth to this association right?)

I then had the idea of using Conversation as a proxy to Reservations, like this:

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
Since there is no belongs_to through in Rails to use in Reservation, other posts in SO suggest using has_one trough instead, just like I did above.

The problem is that conversation has_many reservations, and does not belong_to a reservation (like it does belong to a Tourist and HotelOwner).

It's not only semantics that bother me. If I do hotel_owner.reservations.create(tourist: Tourist.last), it does create the Reservation, but the join model Conversation is not created, leaving reservation.conversation nil.

After a simple hotel_owner.reload, hotel_owner.reservations return nil.

What is the correct database design and Rails association model for something like this?

thanks
iosman

Reply
Reply
Reply
Reply
Reply
Reply
Join the discussion
Create an account Log in

Want to stay up-to-date with Ruby on Rails?

Join 85,376+ developers who get early access to new tutorials, screencasts, articles, and more.

    We care about the protection of your data. Read our Privacy Policy.