在事务脚本中将 ActiveRecord 结果转换为 json

Car*_*Car 7 ruby activerecord json rspec ruby-on-rails

我已经看过很多关于这个的帖子,但似乎没有一个解决方案适用于这个应用程序。我有一个事务脚本 CreateContact,它在添加到数据库时返回一个成功对象:

class CreateContact < TransactionScript
  def run(params)
    contact = Contact.create(params)
    return success(contact: contact)
  end
end
Run Code Online (Sandbox Code Playgroud)

这是我的测试代码:

require 'spec_helper'

describe CreateContact do

  it_behaves_like('TransactionScripts')
  let(:script) {CreateContact.new}

  it "creates a contact" do
    contact = CreateContact.run({:name=>'contact1', :email=>'me@email.com', :phoneNum=>'1234567'})
    expect(contact.success?).to eq(true)
    expect(contact.name).to eq('contact1')
    expect(contact.email).to eq('me@email.com')
    expect(contact.phoneNum).to eq('1234567')
  end
end
Run Code Online (Sandbox Code Playgroud)

我尝试了几种解析散列或 JSON 的方法:在 Contact.create 中拆分 params 散列,将“.to_json”和“JSON.parse”添加到成功对象值,在整个成功对象上调用两者,以及调用'.to_a.map(&:serializable_hash)'。我还尝试在 '.property'、'[:key]' 和 '['property']' 格式之间转换测试代码属性。'['property']' 是唯一一个似乎返回任何东西的函数,但它只返回“property”(而不是一个值)。

When running the tests I can actually see that the ActiveRecord object is created successfully, and some of these techniques will parse if I call them in binding.pry, but when I try to implement them in the code the tests still turn up nil values. Can anyone see what I'm doing wrong?

Pat*_*ity 9

为了一个ActiveRecord对象转换为JSON般的哈希,你可以使用as_json的方法从活动模型JSON序列

hash = contact.as_json
#=> {"id"=>1, "name"=>"contact1", ...}
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用hash["attribute"]. 但是,您将无法调用hash[:attribute]hash.attribute

hash["name"]   #=> "contact1"
hash[:name]    #=> nil
hash.name      #=> NoMethodError: undefined method `name' for {}:Hash
Run Code Online (Sandbox Code Playgroud)

如果您想将该行为添加到散列,您可以从散列构建一个OpenStruct

hash2 = OpenStruct.new(contact.as_json)

hash2["name"]  #=> "contact1"
hash2[:name]   #=> "contact1"
hash.name      #=> "contact1"
Run Code Online (Sandbox Code Playgroud)

如果您只需要 JSON 作为一个实际的String,请使用to_json

json = contact.to_json
#=> "{\"id\":1,\"name\":\"contact1\",...}"
Run Code Online (Sandbox Code Playgroud)