使用ActiveResource保存时,"为数据分配器未定义"

ale*_*ool 6 ruby activeresource

我错过了什么?我正在尝试使用Active资源的休息服务,我有以下内容:

class User < ActiveResource::Base
  self.site = "http://localhost:3000/"
  self.element_name = "users"
  self.format = :json
end

user = User.new(
        :name => "Test",
        :email => "test.user@domain.com")

p user 
if user.save
  puts "success: #{user.uuid}"
else
  puts "error: #{user.errors.full_messages.to_sentence}"
end
Run Code Online (Sandbox Code Playgroud)

并为用户输出以下内容:

#<User:0x1011a2d20 @prefix_options={}, @attributes={"name"=>"Test", "email"=>"test.user@domain.com"}>
Run Code Online (Sandbox Code Playgroud)

而这个错误:

/Library/Ruby/Gems/1.8/gems/activeresource-3.0.10/lib/active_resource/base.rb:1233:in `new': allocator undefined for Data (TypeError)
    from /Library/Ruby/Gems/1.8/gems/activeresource-3.0.10/lib/active_resource/base.rb:1233:in `load'
from /Library/Ruby/Gems/1.8/gems/activeresource-3.0.10/lib/active_resource/base.rb:1219:in `each'
    from /Library/Ruby/Gems/1.8/gems/activeresource-3.0.10/lib/active_resource/base.rb:1219:in `load'
    from /Library/Ruby/Gems/1.8/gems/activeresource-3.0.10/lib/active_resource/base.rb:1322:in `load_attributes_from_response'
    from /Library/Ruby/Gems/1.8/gems/activeresource-3.0.10/lib/active_resource/base.rb:1316:in `create_without_notifications'
    from /Library/Ruby/Gems/1.8/gems/activeresource-3.0.10/lib/active_resource/base.rb:1314:in `tap'
    from /Library/Ruby/Gems/1.8/gems/activeresource-3.0.10/lib/active_resource/base.rb:1314:in `create_without_notifications'
    from /Library/Ruby/Gems/1.8/gems/activeresource-3.0.10/lib/active_resource/observing.rb:11:in `create'
    from /Library/Ruby/Gems/1.8/gems/activeresource-3.0.10/lib/active_resource/base.rb:1117:in `save_without_validation'
    from /Library/Ruby/Gems/1.8/gems/activeresource-3.0.10/lib/active_resource/validations.rb:87:in `save_without_notifications'
    from /Library/Ruby/Gems/1.8/gems/activeresource-3.0.10/lib/active_resource/observing.rb:11:in `save'
    from import_rest.rb:22
Run Code Online (Sandbox Code Playgroud)

如果我用户为我的休息服务卷曲,那就像:

curl -v -X POST -H 'Content-Type: application/json' -d '{"name":"test curl", "email":"test@gmail.com"}' http://localhost:3000/users
Run Code Online (Sandbox Code Playgroud)

回复:

{"email":"test@gmail.com","name":"test curl","admin":false,"uuid":"afb8c98b-562a-4603-bbe4-f8f0816cef0d","creation_limit":5}
Run Code Online (Sandbox Code Playgroud)

phs*_*phs 13

有一个内置类型命名Data,其目的相当神秘.你似乎碰到了它:

$ ruby -e 'Data.new'
-e:1:in `new': allocator undefined for Data (TypeError)
  from -e:1
Run Code Online (Sandbox Code Playgroud)

问题是,它是如何实现的?最后一个堆栈框架将我们放在这里.所以,它看起来Data像是在呼唤find_or_create_resource_for.这里的代码分支很可能:

$ irb
>> class C
>>   end
=> nil
>> C.const_get('Data')
=> Data
Run Code Online (Sandbox Code Playgroud)

这导致我怀疑你有一个属性或类似浮动命名,:data或者"data",即使你没有提到上面的一个.你呢?特别是,似乎我们有一个带有子哈希的JSON响应,其键是"数据".

这是一个可以触发精心设计的输入错误的脚本,但不是来自您发布的响应:

$ cat ./activeresource-oddity.rb
#!/usr/bin/env ruby

require 'rubygems'
gem 'activeresource', '3.0.10'
require 'active_resource'

class User < ActiveResource::Base
  self.site = "http://localhost:3000/"
  self.element_name = "users"
  self.format = :json
end

USER = User.new :name => "Test", :email => "test.user@domain.com"

def simulate_load_attributes_from_response(response_body)
  puts "Loading #{response_body}.."
  USER.load User.format.decode(response_body)
end

OK = '{"email":"test@gmail.com","name":"test curl","admin":false,"uuid":"afb8c98b-562a-4603-bbe4-f8f0816cef0d","creation_limit":5}'
BORKED = '{"data":{"email":"test@gmail.com","name":"test curl","admin":false,"uuid":"afb8c98b-562a-4603-bbe4-f8f0816cef0d","creation_limit":5}}'

simulate_load_attributes_from_response OK
simulate_load_attributes_from_response BORKED
Run Code Online (Sandbox Code Playgroud)

生产..

$ ./activeresource-oddity.rb 
Loading {"email":"test@gmail.com","name":"test curl","admin":false,"uuid":"afb8c98b-562a-4603-bbe4-f8f0816cef0d","creation_limit":5}..
Loading {"data":{"email":"test@gmail.com","name":"test curl","admin":false,"uuid":"afb8c98b-562a-4603-bbe4-f8f0816cef0d","creation_limit":5}}..
/opt/local/lib/ruby/gems/1.8/gems/activeresource-3.0.10/lib/active_resource/base.rb:1233:in `new': allocator undefined for Data (TypeError)
    from /opt/local/lib/ruby/gems/1.8/gems/activeresource-3.0.10/lib/active_resource/base.rb:1233:in `load'
    from /opt/local/lib/ruby/gems/1.8/gems/activeresource-3.0.10/lib/active_resource/base.rb:1219:in `each'
    from /opt/local/lib/ruby/gems/1.8/gems/activeresource-3.0.10/lib/active_resource/base.rb:1219:in `load'
    from ./activeresource-oddity.rb:17:in `simulate_load_attributes_from_response'
    from ./activeresource-oddity.rb:24
Run Code Online (Sandbox Code Playgroud)

如果我是你,我会打开/Library/Ruby/Gems/1.8/gems/activeresource-3.0.10/lib/active_resource/base.rb,load_attributes_from_response在1320行找到并暂时改变

load(self.class.format.decode(response.body))
Run Code Online (Sandbox Code Playgroud)

load(self.class.format.decode(response.body).tap { |decoded| puts "Decoded: #{decoded.inspect}" })
Run Code Online (Sandbox Code Playgroud)

..并再次重现错误,看看你的json解码器真正出现了什么.