2.7.0 :033 > user4.contact_request(user5) Connection Exists? (0.3ms) SELECT 1 AS one FROM "connections" WHERE "connections"."user_id" = ? AND "connections"."contact_id" = ? LIMIT ? [["user_id", 7], ["contact_id", 8], ["LIMIT", 1]] TRANSACTION (0.1ms) begin transaction Connection Create (1.1ms) INSERT INTO "connections" ("user_id", "contact_id", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["user_id", 7], ["contact_id", 8], ["created_at", "2021-04-19 23:45:32.553041"], ["updated_at", "2021-04-19 23:45:32.553041"]] TRANSACTION (0.1ms) rollback transaction Traceback (most recent call last): 4: from (irb):32 3: from (irb):33:in `rescue in irb_binding' 2: from app/models/user.rb:49:in `contact_request' 1: from app/models/user.rb:50:in `block in contact_request' ActiveRecord::StatementInvalid (SQLite3::SQLException: no such table: main.contacts)
class User < ApplicationRecord # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable has_many :developments, dependent: :destroy has_many :connections has_many :connections, dependent: :destroy has_many :contacts, -> { where connections: { status: :accepted }}, through: :connections has_many :requested_contacts, -> { where connections: {status: :requested}}, through: :connections, source: :contact has_many :pending_contacts, -> { where connections: { status: :pending }}, through: :connections, source: :contact has_many :blocked_contacts, -> { where connections: { status: :blocked }}, through: :connections, source: :contact
class Connection < ApplicationRecord belongs_to :user belongs_to :contact, class_name: 'User' enum status: {pending: 0, requested: 1, accepted: 2, blocked: 3} # id: 1 # contact: 2 # user_id: 1, contact_id: 2, status: :requested # user_id: 2, contact_id: 1, status: :pending end
def contact_request(contact) unless self == contact || Connection.where(user: self, contact: contact).exists? transaction do Connection.create(user: self, contact: contact, status: :pending) Connection.create(user: contact, contact: self, status: :requested) end end end
def accept_request(contact) transaction do Connection.find_by(user: self, contact: contact, status: [:requested])&.accepted! Connection.find_by(user: contact, contact: self, status: [:pending])&.accepted! end end