Amer Bearat
Amer Bearat

Reputation: 946

rails console rollback on create rails

I have a button called conversation when the user click on it, it creates conversation as record in the database. The issue is if there is 3 users userA, userB, and userC,

if userB click on conversation button to message userA, it will create conversation record fine. but then if userC click on conversation button to message userA, the record wont save and i get rollback

enter image description here

conversation controller:

class ConversationsController < ApplicationController
before_action :authenticate_user!

def index
  @conversations = Conversation.involving(current_user)
end

def create
  if Conversation.between(params[:sender_id], params[:recipient_id]).present?
  @conversation = Conversation.between(params[:sender_id], params[:recipient_id]).first
else
  @conversation = Conversation.create(conversation_params)
end

redirect_to conversation_messages_path(@conversation) 

end

private
  def conversation_params
    params.permit(:sender_id, :recipient_id)
  end
end

the error happens on this line

    redirect_to conversation_messages_path(@conversation) 

conversation model:

class Conversation < ApplicationRecord
  belongs_to :sender, foreign_key: :sender_id, class_name: "User"
  belongs_to :recipient, foreign_key: :recipient_id, class_name: "User"

 has_many :messages, dependent: :destroy
 validates_uniqueness_of :sender_id, :recipient_id

 scope :involving, -> (user) {
   where("conversations.sender_id = ? OR conversations.recipient_id = ?", user.id, user.id)
 }

scope :between, -> (user_A, user_B) {
  where("(conversations.sender_id = ? AND conversations.recipient_id = ?) OR (conversations.sender_id = ? AND conversations.recipient_id = ?)", user_A, user_B, user_B, user_A)
 }
end

the error happened because of this line

  validates_uniqueness_of :sender_id, :recipient_id

Upvotes: 1

Views: 196

Answers (1)

SteveTurczyn
SteveTurczyn

Reputation: 36860

Your uniqueness should be scoped, otherwise you're just setting two independent uniquenesses and (in your example) sender can only have one conversation in the entire database and recipient can only have one conversation in the entire database.

The correct way to do it is...

validates :sender_id, uniqueness: { scope: :recipient_id, message: "there is already a converation between these people" }

The scoped means there can only be one record with this sender for this recipient.

Upvotes: 2

Related Questions