我正在开发集成Scale的API,并且无法在我的Rails控制器中解析响应。
从Scale发布到控制器的参数类似于:
Parameters: {"task"=>{"task_id"=>"589253a3b36b2d...1fe68", "created_at"=>"2017-02-01T21:31:15.607Z", "completed_at"=>"2017-02-01T21:31:15.612Z", "callback_url"=>"http://...", "type"=>"categorization", "status"=>"completed", "instruction"=>"Is this company public or private?", "params"=>{"allow_multiple"=>true, "categories"=>["NCI....
我的控制器方法:
def create
# check authorization
callback = $scale.build_callback params, 'task', callback_key: request.headers['scale-callback-auth']
response = callback.response # Response content hash (code and result)
task = callback.task # Scale::Resources::Task object
return nil if ScaleWebhook.exists?(task_id: task.task_id)
ScaleWebhook.create!(task_id: task.task_id, response: task.response)
end
在控制台中,当我得到Scale::Resources::Task
时,我可以执行task.task_id
之类的操作。示例对象:
#<Scale::Resources::Task:0x007fad81573e70 @task_id="589252b2b36b2d060061fd19", @type="categorization", @instruction="Is this company public or private?", @params={"allow_multiple"=>false, "categories"=>["public", "private"], "attachment"=>"http://www.google.com/", "attachment_type"=>"website"}, @urgency="day", @response=nil, @callback_url="http://www.example.com/callback", @status="pending", @created_at=2017-02-01 21:27:14 UTC, @completed_at=nil>
但是我的Rails控制器正在执行此操作:
ScaleWebhook Exists (0.8ms) SELECT 1 AS one FROM "scale_webhooks" WHERE "scale_webhooks"."task_id" = $1 LIMIT $2 [["task_id", "#<ActionController::Parameters:0x007fd680575130>"], ["LIMIT", 1]]
SQL (0.4ms) INSERT INTO "scale_webhooks" ("task_id", "response", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["task_id", "#<ActionController::Parameters:0x007fd680575130>"], ["response", "#<ActionController::Parameters:0x007fd68058d578>"], ["created_at", 2017-02-01 21:31:15 UTC], ["updated_at", 2017-02-01 21:31:15 UTC]]
如您所见,它将#<ActionController::Parameters
插入数据库,而不是值。我猜这与rails&#39;有关。强大的参数,但我尝试了几种允许的方式,甚至允许所有参数作为测试,我仍然无法访问#<ActionController::Parameters
以外的任何内容。
我使用build_callback
提供的scaleapi-ruby
方法,因为它验证了从Scale发送的auth_key,但我想我真的不需要用它来解析进一步响应,如params['task_id']
之类的作品。
更新: 看起来模型被设置为序列化所有参数,序列化关闭,我得到以下错误:
TypeError (can't cast ActionController::Parameters):
app/controllers/scale_api_controller.rb:13:in `create'
这是第13行:
return nil if ScaleWebhook.exists?(task_id: task.task_id)
在评论第13行时,我遇到的问题与#<ActionController::Parameters:0x007fd6815317b8>
相似,而不是实际的任务ID。
更新2:
使用binding.pry,我得到了:
#<Scale::Resources::Task:0x007fd919aa1f78
@callback_url=nil,
@completed_at=nil,
@created_at=nil,
@instruction=nil,
@params={},
@response=<ActionController::Parameters {"category"=>["Blackish", "Sherlock"]} permitted: false>,
@status=nil,
@task_id=
<ActionController::Parameters {"task"=>{"task_id"=>"58925f...00620894", "created_at"=>"2017-02-01T22:20:25.921Z", "completed_at"=>"2017-02-01T22:20:25.927Z", "callback_url"=>"...", "type"=>"categorization", "status"=>"completed", "instruction"=>"Is this company public or private?", "params"=>{"allow_multiple"=>true, "categories"=>["Arrow", "Last Man on Earth", "The Real O'Neals", "Blackish", "Sherlock", "Riverdale"], "attachment"=>"...", "attachment_type"=>"image"}, "is_test"=>true, "urgency"=>"day", "metadata"=>{"name"=>"...", "user_id"=>1}, "response"=>{"category"=>["Blackish", "Sherlock"]}}, "response"=>{"category"=>["Blackish", "Sherlock"]}, "task_id"=>"58925f29b36b2d0600620894", "controller"=>"scale_api", "action"=>"create", "scale_api"=>{"task"=>{"task_id"=>"58925f29.....600620894", "created_at"=>"2017-02-01T22:20:25.921Z", "completed_at"=>"2017-02-01T22:20:25.927Z", "callback_url"=>"...", "type"=>"categorization", "status"=>"completed", "instruction"=>"Is this company public or private?", "params"=>{"allow_multiple"=>true, "categories"=>["Arrow", "Last Man on Earth", "The Real O'Neals", "Blackish", "Sherlock", "Riverdale"], "attachment"=>"https://s3.amazonaws.com...", "attachment_type"=>"image"}, "is_test"=>true, "urgency"=>"day", "metadata"=>{"name"=>"...", "user_id"=>45}, "response"=>{"category"=>["Blackish", "Sherlock"]}}, "response"=>{"category"=>["Blackish", "Sherlock"]}, "task_id"=>"58925f29b...b2d0600620894"}} permitted: false>,
@type=nil,
@urgency=nil>
答案 0 :(得分:1)
问题是ActionController :: Parameters意味着作为传递给ActiveRecord构建器方法的唯一数据。 (创建!,创建,新建等)当你说
时ScaleWebhook.create!(task_id: task.task_id, response: task.response)`
您没有将ActionController :: Parameters对象传递给.create!
。您正在传递一个常规哈希值,其中一个值恰好是ActionController :: Parameters的一个实例。由于该列设置为接受序列化数据,因此AR将该实例视为另一个要序列化的对象,并将其原始形式推送到列中。
你需要这样做才能使传递给.create!
进行质量分配的唯一数据是task.response中的ActionController :: Parameters对象。您仍然可以在块中设置其他值。
此外,task.task_id似乎也返回了一个ActionController :: Parameters。您可能希望通过说task.task_id.require(:task).require(:task_id)
总而言之,你可能想要这样的东西:
ScaleWebhook.create!(task.response) do |scale_web_hook|
scale_web_hook.task_id = task.task_id.require(:task).require(:task_id)
end
此时,您可能会根据您的型号获得分配/质量分配错误。确保允许您允许的所有数据通过批量分配到您的模型上。
我不熟悉Scale API,但我建议稍微阅读一下文档。可能有一种更优雅的方式来访问task_id。
答案 1 :(得分:1)
问题是由于宝石中的错误引起的。有关详细信息,请参阅this issue。
问题与Rails如何处理参数(
ActionController::Parameters
)以及此库如何管理它们(ActiveSupport::HashWithIndifferentAccess
)之间的冲突有关。此gem的先前版本错误地使用了Scale::to_hash中的
ActiveSupport::HashWithIndifferentAccess
构造函数。现在,通过对同一method进行一些检查来修复错误。如果您无法更新gem(或不想更新),您可能希望使用
scale.build_callback
将哈希值传递给ActionController::Parameters#to_unsafe_hash
:callback = $scale.build_callback params.to_unsafe_hash, 'task', callback_key: request.headers['scale-callback-auth']