问题
当我调用Hash#merge函数时,我很难理解为什么我的Hash被当作字符串对待。调用以下代码时,我将收到一个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变量视为字符串而不是哈希。根据下面的消息来源,我看不出这是怎么回事。
来源
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相关信息
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>"}日志
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'发布于 2018-08-14 12:16:44
哈希没有被视为字符串;您正在误读错误。
我不知道你的回溯是不是被什么东西突然截断了,或者你刚刚修改了重要的部分,但错误不是你想的那样。
您调用merge的事实与您的问题无关,即 method you are calling在其论点上调用了merge .它是作为to_json-built字符串传递的,而不是它所期望的哈希。
您需要删除调用中的.to_json。
发布于 2018-08-14 12:31:05
对散列调用to_json会将其转换为字符串。
irb(main):001:0> { foo: 'bar' }.to_json.class
=> StringWHile签名是Aws::SNS::Topic#publish(options = {}) ⇒ Types::PublishResponse。
所以你应该称它为:
topic.publish(
subject: 'LAB_COMPLETE',
message: lab_attribs.merge(full_name: current_user.full_name).to_json
)您可以通过使用活动作业和一些基本的哈希操作来清理整个混乱的示例:
# app/jobs/publish_job.rb
class PublishJob < ApplicationJob
queue_as :default
def perform(**options)
sns = Aws::SNS::Resource.new
topic = sns.topic(Rails.application.secrets.lab_results_topic)
topic.publish(options)
end
end# ...
def create
lab = Lab.new(lab_attributes)
if lab.save
PublishJob.perform_now(
subject: 'LAB_COMPLETE',
message: lab_attributes.merge(full_name: current_user.full_name).to_json
)
render json: { lab_name: lab.name }
else
render json: { status: 422, errors: lab.errors }
end
end
private
def lab_attributes
create_params.slice(:duration, :final_grade, :cpe, :user_id).merge(
completed: DateTime.now,
name: create_params[:lab_name]
)
endhttps://stackoverflow.com/questions/51840178
复制相似问题