Ruby on rails 创建rails上的rails控制台回滚
我有一个名为conversation的按钮,当用户单击它时,它会在数据库中创建一个作为记录的对话。问题是如果有3个用户userA、userB和userC 若userB点击对话按钮发送信息给userA,它将创建对话记录。但是,如果userC单击对话按钮发送消息userA,记录将不会保存,我将得到回滚 对话控制器:Ruby on rails 创建rails上的rails控制台回滚,ruby-on-rails,ruby,Ruby On Rails,Ruby,我有一个名为conversation的按钮,当用户单击它时,它会在数据库中创建一个作为记录的对话。问题是如果有3个用户userA、userB和userC 若userB点击对话按钮发送信息给userA,它将创建对话记录。但是,如果userC单击对话按钮发送消息userA,记录将不会保存,我将得到回滚 对话控制器: class ConversationsController < ApplicationController before_action :authenticate_user!
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
对话模式:
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
您的唯一性应该是有范围的,否则您只需要设置两个独立的唯一性,并且(在您的示例中)发送方在整个数据库中只能有一个会话,接收方在整个数据库中只能有一个会话 正确的方法是
validates :sender_id, uniqueness: { scope: :recipient_id, message: "there is already a converation between these people" }
范围限定的表示此收件人只能有一条与此发件人相关的记录
validates_uniqueness_of :sender_id, :recipient_id
validates :sender_id, uniqueness: { scope: :recipient_id, message: "there is already a converation between these people" }