为什么这个哈希被视为一个字符串?

pyR*_*bit 0 ruby ruby-on-rails

问题

我很难理解为什么在调用Hash#merge函数时我的Hash被视为String .在调用以下代码时,我会收到一个NoMethodError method 'merge' for #<String:0x000...

抛出错误的代码行如下:topic.publish({subject: 'LAB_COMPLETE', message: lab_attribs.merge(full_name: current_user.full_name)}.to_json).出于某种原因,Ruby将lab_attribs变量视为String而不是Hash.根据下面的来源,我不可能看到这是怎么回事.

资源

lab_attribs = {
    name: create_params['lab_name'],
    completed: DateTime.now,
    duration: create_params['duration'],
    final_grade: create_params['final_grade'],
    cpe: create_params['cpe'],
    user_id: create_params['user_id']
}

lab = Lab.new(lab_attribs)

if lab.save
  logger.debug("lab_attribs class: #{lab_attribs.class}, lab_attribs value: #{lab_attribs}" )
  sns = Aws::SNS::Resource.new
  topic = sns.topic(Rails.application.secrets.lab_results_topic)
  topic.publish({subject: 'LAB_COMPLETE', message: lab_attribs.merge(full_name: current_user.full_name)}.to_json)

  render json: { lab_name: lab.name }
else
  render json: { status: 422, errors: lab.errors }
end
Run Code Online (Sandbox Code Playgroud)

相关信息

logger.debug 输出以下内容:

lab_attribs class: Hash, lab_attribs value: {:name=>"Updating Firewall Rules", :completed=>Tue, 14 Aug 2018 11:36:01 +0000, :duration=>"1 minute", :final_grade=>"0", :cpe=>"0", :user_id=>"<snipped>"}
Run Code Online (Sandbox Code Playgroud)
  • Ruby版本:2.3.1
  • Rails版本:5.1

日志

I, [2018-08-14T11:36:00.943514 #1930]  INFO -- : [d9f4566a-5b25-4e07-ace3-06f301ecf0cb] Started POST "/api/v1/labs" for 172.68.65.103 at 2018-08-14 11:36:00 +0000
I, [2018-08-14T11:36:00.946228 #1930]  INFO -- : [d9f4566a-5b25-4e07-ace3-06f301ecf0cb] Processing by Api::V1::LabsController#create as */*
I, [2018-08-14T11:36:00.946311 #1930]  INFO -- : [d9f4566a-5b25-4e07-ace3-06f301ecf0cb]   Parameters: {"lab"=>{"lab_name"=>"[FILTERED]", "task1"=>"Saved a local copy of the firewall rules", "score1"=>"0", "weight1"=>"50", "task2"=>"Blocked port 3600", "score2"=>"0", "weight2"=>"50", "final_grade"=>"0", "cpe"=>"0", "duration"=>"1 minute", "user_id"=>"<snipped>"}}
...<snipped DB calls>... 
D, [2018-08-14T11:36:01.408369 #1930] DEBUG -- : [d9f4566a-5b25-4e07-ace3-06f301ecf0cb] lab_attribs class: Hash, lab_attribs value: {:name=>"Updating Firewall Rules", :completed=>Tue, 14 Aug 2018 11:36:01 +0000, :duration=>"1 minute", :final_grade=>"0", :cpe=>"0", :user_id=>"<snipped>"}
I, [2018-08-14T11:36:01.414112 #1930]  INFO -- : [d9f4566a-5b25-4e07-ace3-06f301ecf0cb] Completed 500 Internal Server Error in 468ms (ActiveRecord: 26.7ms)
F, [2018-08-14T11:36:01.414612 #1930] FATAL -- : [d9f4566a-5b25-4e07-ace3-06f301ecf0cb]   
F, [2018-08-14T11:36:01.414689 #1930] FATAL -- : [d9f4566a-5b25-4e07-ace3-06f301ecf0cb] NoMethodError (undefined method `merge' for #<String:0x0055e4df9d9558>):
F, [2018-08-14T11:36:01.414720 #1930] FATAL -- : [d9f4566a-5b25-4e07-ace3-06f301ecf0cb]   
F, [2018-08-14T11:36:01.414758 #1930] FATAL -- : [d9f4566a-5b25-4e07-ace3-06f301ecf0cb] app/controllers/api/v1/labs_controller.rb:30:in `create'
Run Code Online (Sandbox Code Playgroud)

mat*_*ewd 6

哈希不被视为一个字符串; 你误读了这个错误.

我不确定你的回溯是否被某些东西惊人地截断,或者你刚刚编写了重要的部分,但错误并不是你认为的那样.

您调用的事实merge与您的问题无关,即您调用publish方法调用merge其参数...您将其作为to_json构建字符串传递,而不是它所期望的哈希.

你需要删除.to_json你的电话.