Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting ActiveRecord results to json in transaction script

I've seen a number of posts on this but none of the solutions seem to be working for this application. I have a transaction script, CreateContact, which returns a success object when added to the database:

class CreateContact < TransactionScript
  def run(params)
    contact = Contact.create(params)
    return success(contact: contact)
  end
end

Here's my test code:

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=>'[email protected]', :phoneNum=>'1234567'})
    expect(contact.success?).to eq(true)
    expect(contact.name).to eq('contact1')
    expect(contact.email).to eq('[email protected]')
    expect(contact.phoneNum).to eq('1234567')
  end
end

I've tried several ways of parsing to a hash or JSON: splitting apart the params hash in Contact.create, adding ".to_json" and "JSON.parse" to the success object value, calling both on the entire success object, and calling '.to_a.map(&:serializable_hash)'. I've also tried converting the test code properties between the '.property', '[:key]', and '['property']' formats. '['property']' is the only one that seems to return anything, but it only returns "property" (instead of a value).

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?

like image 502
Car Avatar asked Aug 01 '14 07:08

Car


1 Answers

To convert an ActiveRecord object to a JSON-like Hash, you can use the as_json method from the Active Model JSON Serializer:

hash = contact.as_json
#=> {"id"=>1, "name"=>"contact1", ...}

You can then access the contents of the hash with hash["attribute"]. However, you will not be able to call hash[:attribute] or hash.attribute:

hash["name"]   #=> "contact1"
hash[:name]    #=> nil
hash.name      #=> NoMethodError: undefined method `name' for {}:Hash

If you want to add that behavior to the hash you can build an OpenStruct from the hash:

hash2 = OpenStruct.new(contact.as_json)

hash2["name"]  #=> "contact1"
hash2[:name]   #=> "contact1"
hash.name      #=> "contact1"

If you just need the JSON as an actual String, use to_json:

json = contact.to_json
#=> "{\"id\":1,\"name\":\"contact1\",...}"
like image 129
Patrick Oscity Avatar answered Sep 29 '22 14:09

Patrick Oscity