Упрощение запроса с помощью Rails

#sql #ruby-on-rails

#sql #ruby-on-rails

Вопрос:

У меня есть этот код:

 @messages = Message.where(["user_id = ? AND receiver_uuid = ? OR user_id = ? AND receiver_uuid = ?", current_user.id, @friend_user[0].id, @friend_user[0].id, current_user.id])
 

Мне нужно искать связь между двумя идентификаторами в 2 столбцах.

Мой метод создания:

     def send_message
        @message = Message.new(user: current_user, receiver_uuid: message_params[:receiver_uuid], body: message_params[:body])        
        respond_to do |format|
            if @message.save
                flash[:notice] = "Mensagem enviada com sucesso!"
                format.html { redirect_to messenger_path(message_params[:receiver_uuid]) }             
            else
                flash[:alert] = "Erro ao enviar a mensagem!"
                format.html { redirect_to messenger_path(message_params[:receiver_uuid]) }             
            end
        end
    end
 

Ответ №1:

Если вы ищете упрощения, начните с использования моделей вместо идентификаторов в вашем запросе. Вы можете сделать что-то вроде этого:

@messages = Message.where(user: current_user, receiver: @friend_user).or(Message.where(user: @friend_user, receiver: current_user))

Или еще лучше:

@messages = current_user.messages.where(receiver: @friend_user).or(@friend_user.messages.where(receiver: current_user))

Конечно, это предполагает, что ваша модель сообщений имеет :receiver отношение, но нет причин, по которым она не должна его иметь.

Ответ №2:

Один из способов сделать это…

В вашей модели:

 # message.rb
class Message
  scope :by_user_id, -> (user_id) { where(user_id: user_id) }
  scope :by_receiver_uuid, -> (receiver_uuid) { where(receiver_uuid: receiver_uuid) }
end
 

И тогда вы можете сделать:

 # messages_controller.rb (or wherever)
ids = [current_user.id, @friend_user[0].id]
messages = Message.by_user_id( ids ) | Message.by_receiver_uuid( ids )