user3162553 user3162553 - 2 months ago 13
SQL Question

Conditionally Saving has_many_through Relationships

In Rails, how would one conditionally associated records on a

has_many_through
relationship? Using the following Rails docs example:

class Physician < ApplicationRecord
has_many :appointments
has_many :patients, through: :appointments
end

class Appointment < ApplicationRecord
belongs_to :physician
belongs_to :patient
end

class Patient < ApplicationRecord
has_many :appointments
has_many :physicians, through: :appointments
end


Suppose I wanted to have an appointment reference exactly two physicians. That is, there will not be any appointment record one there is less than two physicians assigned. However, how could that appointment then reference each physician?

Example

Basically, I want to keep track of users liking other users and mutual likes between them. A connection is established when both users like each other. But I don't want a connection when only one user likes another but it is not reciprocal.

When User A likes User B. A "like" is created.
When User B likes User A. A "like" is created. A "connection" is also created.

The connection should be able to call:
connection.users


The user should be able to call:
user.likes

user.connections


The problem that I'm having is how can that relationship table know when it is mutual?

Answer

For the original question, a connection doesnt make a difference between the two users, so i would model it as a one to many relationship and validate it only has two users.

A like has two users, the liker (giver of the like) and the likee (receiver of the like). Every time you create new like, you should check if the likee also likes the liker. If likee.likes.where(likee: liker)? If yes, then create the new connection with both users.

class User < ApplicationRecord
    has_many :likes
    has_many :connections
end

class Like < ApplicationRecord
    belongs_to :user, :foreign_key => 'liker_id'
    belongs_to :user, :foreign_key => 'likee_id'
end

class Connection < ApplicationRecord
    has_many :likes
    has_many :users, through: likes
end

I want to add that i am not 100% sure of this as i am currently learning Rails myself. But this is what I came up with and hopefully its useful (and correct).