为什么即使我清除了数据库,我的控制器也仍然期望检索数据

时间:2019-03-31 12:23:17

标签: ruby-on-rails ruby database postgresql postgresql-9.3

我使用postgresql作为数据库制作了一个Rails应用程序,您可以在其中与用户联系并从他们的帖子中向他们发送消息。我的种子文件创建了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 :(得分:0)

session变量在浏览器会话期间有效。因此,此错误意味着您在登录时删除了数据库记录,并且没有适当地调整session[:private_conversations]

您要么需要从session[:private_conversations]中删除已删除的ID,要么将找到的ID调整为可以,只找到一些即可。

我会将您的代码更改为此:

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期望提供的所有ID都将存在。 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