为什么即使我清除了数据库,我的控制器仍希望检索数据
Why does my controller keep expecting to retrieve data even though I cleared out the database
我正在制作一个 rails 应用程序,使用 postgresql 作为数据库,您可以在其中与用户联系并从他们的帖子中向他们发送消息。我的种子文件创建了 10 个测试用户,我正在检查向其他用户发送消息的功能,但是 运行 用户无法测试,所以我跳上 rails 控制台并清除了对话和消息 table 所以我可以删除数据库中的所有关系,但从那以后我一直收到这个错误:
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 行更改为
时,代码似乎 "work"
if (user_signed_in? && @private_conversations_windows)
但是当我这样做并与用户创建新聊天时,新聊天关系的创建会访问数据库,但聊天 window 不会显示。
更新:
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
session
变量在浏览器会话期间有效。所以这个错误的意思是你登录时删除了数据库记录,而你没有适当调整session[:private_conversations]
。
您要么需要从 session[:private_conversations]
中删除已删除的 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]
时,(大概是当有人 closes/opens 一个新的对话时)你可以将它设置为仅那些仍然存在的。
您提到以下内容似乎有效:
if (user_signed_in? && @private_conversations_windows)
鉴于您发布的代码,我相信您实际上永远不会将 @private_conversations_windows
设置为 []
以外的任何值。原因是,您当前正在尝试设置该变量,因此此时它应该为 nil。因为它总是 nil,所以你永远不会落入实际查询数据库的 if
的那一边。当然,它不会再出错了,但那是因为它不再做任何有用的事情了。它基本上等同于:
def opened_conversations_windows
@private_conversations_windows = []
end
我正在制作一个 rails 应用程序,使用 postgresql 作为数据库,您可以在其中与用户联系并从他们的帖子中向他们发送消息。我的种子文件创建了 10 个测试用户,我正在检查向其他用户发送消息的功能,但是 运行 用户无法测试,所以我跳上 rails 控制台并清除了对话和消息 table 所以我可以删除数据库中的所有关系,但从那以后我一直收到这个错误:
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 行更改为
时,代码似乎 "work"if (user_signed_in? && @private_conversations_windows)
但是当我这样做并与用户创建新聊天时,新聊天关系的创建会访问数据库,但聊天 window 不会显示。 更新:
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
session
变量在浏览器会话期间有效。所以这个错误的意思是你登录时删除了数据库记录,而你没有适当调整session[:private_conversations]
。
您要么需要从 session[:private_conversations]
中删除已删除的 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]
时,(大概是当有人 closes/opens 一个新的对话时)你可以将它设置为仅那些仍然存在的。
您提到以下内容似乎有效:
if (user_signed_in? && @private_conversations_windows)
鉴于您发布的代码,我相信您实际上永远不会将 @private_conversations_windows
设置为 []
以外的任何值。原因是,您当前正在尝试设置该变量,因此此时它应该为 nil。因为它总是 nil,所以你永远不会落入实际查询数据库的 if
的那一边。当然,它不会再出错了,但那是因为它不再做任何有用的事情了。它基本上等同于:
def opened_conversations_windows
@private_conversations_windows = []
end