Почему мой контроллер продолжает ожидать получения данных, даже если я очистил базу данных - PullRequest
0 голосов
/ 31 марта 2019

Я создаю приложение rails, используя postgresql в качестве базы данных, где вы можете связаться с пользователями и отправлять им сообщения из их сообщений. Мой начальный файл создает 10 тестовых пользователей, и я проверял функциональность для отправки сообщений другим пользователям, но у меня не осталось пользователей для тестирования, поэтому я запрыгнул на консоль rails и очистил таблицу разговоров и сообщений, чтобы я мог удалить все связи в базе данных. но с тех пор я продолжаю получать эту ошибку:

    ActiveRecord::RecordNotFound in PagesController#index
    Couldn't find all Private::Conversations with 'id': (14, 2, 3, 5, 6, 8, 9, 
    10, 11, 1) (found 3 results, but was looking for 10).

Это код в моем действии индекса PagesController:

def index
    @hobby_posts = Post.by_branch('hobby').limit(8)
    @study_posts = Post.by_branch('study').limit(8)
    @team_posts  = Post.by_branch('team').limit(8)
  end

Почему эта ошибка продолжает появляться?

Я пытался полностью удалить базу данных, воссоздать базу данных, повторно запустить миграцию, но это, похоже, не очищает разговоры

это код в моем ApplicationController:

def opened_conversations_windows
    if user_signed_in?
      session[:private_conversations] ||= []
      @private_conversations_windows = Private::Conversation.includes(:recipient, :messages)
                                        .find(session[:private_conversations])
    else
      @private_conversations_windows = []
    end
  end

код, кажется, "работает", когда я изменяю строку if на

if (user_signed_in? && @private_conversations_windows)

но когда я делаю это и создаю новый чат с пользователем, создание нового отношения чата попадает в базу данных, но окно чата не отображается. Обновление:

class Private::ConversationsController < ApplicationController

  def create
    recipient_id = Post.find(params[:post_id]).user.id
    @conversation = Private::Conversation.new(sender_id: current_user.id, 
                                             recipient_id: recipient_id)
    if @conversation.save
      Private::Message.create(user_id: current_user.id, 
                              conversation_id: @conversation.id, 
                              body: params[:message_body])

      add_to_conversations unless already_added?

      respond_to do |format|
        format.js {render partial: 'posts/show/contact_user/message_form/success'}
      end
    else
      respond_to do |format|
        format.js {render partial: 'posts/show/contact_user/message_form/fail'}
      end
    end
  end


  def close 
    @conversation_id = params[:id].to_i
    session[:private_conversations].delete(@conversation_id)
    respond_to do |format|
      format.js  
    end
  end

  private

  def add_to_conversations
    session[:private_conversations] ||= []
    session[:private_conversations] << @conversation.id
  end

  def already_added?
    session[:private_conversations].include?(@conversation.id)
  end

end

1 Ответ

0 голосов
/ 31 марта 2019

session переменные живут в течение сеанса браузера. Таким образом, эта ошибка означает, что вы удалили записи базы данных при входе в систему и не настроили session[:private_conversations] соответствующим образом.

Вам нужно либо удалить удаленные идентификаторы из session[:private_conversations], либо настроить поиск, чтобы он был в порядке, только не найдя их.

Я бы изменил ваш код на это:

def opened_conversations_windows
  if user_signed_in? && session[:private_conversations].present?
    @private_conversations_windows = Private::Conversation.includes(:recipient, :messages)
                                        .where(id: session[:private_conversations])

    # Update the session variable to only have the existing values
    session[:private_conversations] = @private_conversations_windows.map(&:id)
  else
    @private_conversations_windows = []
  end
end

Обратите внимание, что я превратил find() в where(id: ). find ожидает, что все предоставленные идентификаторы будут существовать. where не требует никаких записей для возврата; он просто ищет, и вы получаете то, что получаете.

Кроме того, он выполняет запрос к базе данных только тогда, когда у пользователя фактически открыты личные беседы. Это важно, потому что в противном случае он выполнил бы неправильный запрос, если вы вошли в систему, но у вас не было личных разговоров. (WHERE id IS NULL или что-то в этом роде)

Наконец, у меня есть небольшая очистка переменной сеанса, чтобы установить только те, которые еще существуют в базе данных.

Теперь позже, когда вы установите session[:private_conversations], (предположительно, когда кто-то закрывает / открывает новый разговор), вы можете установить для него только те, которые еще существуют.

Вы упоминаете, что, похоже, сработало:

if (user_signed_in? && @private_conversations_windows)

Учитывая код, который вы разместили, я полагаю, что на самом деле вы никогда не установите @private_conversations_windows на что-либо другое, кроме []. Причина в том, что вы сейчас пытаетесь установить эту переменную, поэтому в настоящий момент она должна быть равна нулю. Поскольку он всегда равен нулю, вы никогда не попадете на сторону if, который фактически запрашивает базу данных. Конечно, это больше не будет ошибкой, но это потому, что он больше не делает ничего полезного. В основном это будет эквивалентно:

def opened_conversations_windows
  @private_conversations_windows = []
end
...