下一行:
User.find(session[:user_id])
其中session[:user_id]
之前已定义:
session[:user_id] = user.id
在规范中工作正常并返回用户模型,但在实际应用程序(开发模式)中它失败:
MOPED: 127.0.0.1:27017 QUERY database=rails_api_development collection=users selector={"_id"=>{"$oid"=>BSON::ObjectId('533c3958616c641142010000')}} flags=[] limit=0 skip=0 batch_size=nil fields=nil runtime: 1.0680ms
Completed 500 Internal Server Error in 15ms
Moped::Errors::QueryFailure - The operation: #<Moped::Protocol::Query
@length=89
@request_id=2
@response_to=0
@op_code=2004
@flags=[]
@full_collection_name="rails_api_development.users"
@skip=0
@limit=0
@selector={"_id"=>{"$oid"=>BSON::ObjectId('533c3958616c641142010000')}}
@fields=nil>
failed with error 10068: "invalid operator: $oid"
See https://github.com/mongodb/mongo/blob/master/docs/errors.md
for details about this error.:
moped (2.0.0.rc1) lib/moped/operation/read.rb:50:in `block in execute'
moped (2.0.0.rc1) lib/moped/node.rb:594:in `block (2 levels) in flush'
当我将find
更改为:
User.find(session[:user_id]['$oid'])
但规格失败了:
1) ApplicationController current_user when current_user is nil and user_id stores in session finds and returns it from db
Failure/Error: expect(subject.send(:current_user)).to eq user
NoMethodError:
undefined method `[]' for BSON::ObjectId('533fae9e616c6464a4010000'):BSON::ObjectId
# ./app/controllers/application_controller.rb:7:in `current_user'
# ./spec/controllers/application_controller_spec.rb:22:in `block (5 levels) in <top (required)>'
在我使用database_cleaner处理真正的数据库的规范中。所以,我猜都一样(但显然不是)
我已尝试为to_s
according to this制作to_json
,user_id
,添加mongoid初始化文件with this,同时尝试使用{{}} {{} 1}} multi_json
个版本 - 没有帮助。
我的应用程序控制器带有规范there
我几乎不希望有人可以提供帮助,考虑到之前这些棘手问题的结果,但无论如何,提前谢谢!
更新 测试失败:
moped
答案 0 :(得分:1)
我之前遇到过类似的问题,问题是会话中BSON::ObjectId
的json表示。正如您所发现的,调用to_s
为我解决了这个问题。您需要确保该会话包含字符串格式的id。因此,无论何时将用户ID分配给会话,请致电to_s
。尝试进行以下更改:
将current_user=
中的ApplicationController
更改为:
def current_user=(user)
@current_user = user
session[:user_id] = user.try(:id).try(:to_s)
end
将规格更改为:
context "and user_id stores in session" do
let(:user) { create(:user) }
before { allow(subject).to receive(:session).and_return({ user_id: user.id.to_s }) }
before { allow(User).to receive(:find).and_return(user) }
it "finds and returns it from db" do
expect(User).to receive(:find)
expect(subject.send(:current_user)).to eq user
end
end