简体   繁体   中英

Rails 3.2 How do I convert model.inspect into a hash?

I'm capturing "point in time" (audit) data about certain model records using the inspect method to dump the state of the record to a string . For example after I've stored a User record in the variable a_user I call inspect and store the results in a string variable archived_user_data :

1.9.3p484 :045 > archived_user_data = a_user.inspect
 => "#<User id: 17, email: \"ray.johnson@breakfs.com\", encrypted_password: \"$2a$10$v3CJZftIyDW/XZpktXXdMOuN1IxMoVmaofcIqEB6kBV....\", created_at: \"2014-04-05 21:42:09\", updated_at: \"2014-04-05 21:43:25\", account_id: 9>" 

1.9.3p484 :046 > archived_user_data
 => "#<User id: 17, email: \"ray.johnson@breakfs.com\", encrypted_password: \"$2a$10$v3CJZftIyDW/XZpktXXdMOuN1IxMoVmaofcIqEB6kBV....\", created_at: \"2014-04-05 21:42:09\", updated_at: \"2014-04-05 21:43:25\", account_id: 9>" 

When the archived_user_data is retrieved sometime in the future, I need to convert it into a hash. Is there a simple way to do this? It looks like hashes converted to strings are usually converted back using eval , but in this case eval(archived_user_data) returns nil .

If you are still free to use Marshal, fine! If not, I suggest you peel down the string to the hash part using

s = archived_user_data.match(/#<User (.*)>/)[1]

after which you can reconstruct the hash using eval

eval("{" + s + "}")

Just do as below using attributes :

Returns a hash of all the attributes with their names as keys and the values of the attributes as values.

archived_user_data = a_user.attributes

You can use Marshal to dump and store any Ruby Object.

Example:

(Using reference from @Arup's code)

data_hash = a_user.attributes
dump_string = Marshal.dump(data_hash)
retrieved_hash = Marshal.load(dump_string)

You can store dump_string in file or database or in any other storage area.

EDIT

Specific case:

2.1.0 :013 > {:a => "b"}.inspect
 => "{:a=>\"b\"}"
2.1.0 :014 > "{id: 17, email: \"ray.johnson@breakfs.com\", encrypted_password: \"$2a$10$v3CJZftIyDW/XZpktXXdMOuN1IxMoVmaofcIqEB6kBV....\", created_at: \"2014-04-05 21:42:09\", updated_at: \"2014-04-05 21:43:25\", account_id: 9}"
 => "{id: 17, email: \"ray.johnson@breakfs.com\", encrypted_password: \"$2a$10$v3CJZftIyDW/XZpktXXdMOuN1IxMoVmaofcIqEB6kBV....\", created_at: \"2014-04-05 21:42:09\", updated_at: \"2014-04-05 21:43:25\", account_id: 9}"
2.1.0 :015 > eval("{id: 17, email: \"ray.johnson@breakfs.com\", encrypted_password: \"$2a$10$v3CJZftIyDW/XZpktXXdMOuN1IxMoVmaofcIqEB6kBV....\", created_at: \"2014-04-05 21:42:09\", updated_at: \"2014-04-05 21:43:25\", account_id: 9}")
 => {:id=>17, :email=>"ray.johnson@breakfs.com", :encrypted_password=>"$2a$10$v3CJZftIyDW/XZpktXXdMOuN1IxMoVmaofcIqEB6kBV....", :created_at=>"2014-04-05 21:42:09", :updated_at=>"2014-04-05 21:43:25", :account_id=>9}

You need to understand that hashes when inspected and stored as string aren't of the form:

"#<User id: 17, email: \"ray.johnson@breakfs.com\", encrypted_password: \"$2a$10$v3CJZftIyDW/XZpktXXdMOuN1IxMoVmaofcIqEB6kBV....\", created_at: \"2014-04-05 21:42:09\", updated_at: \"2014-04-05 21:43:25\", account_id: 9>"

But should be of the form:

"{id: 17, email: \"ray.johnson@breakfs.com\", encrypted_password: \"$2a$10$v3CJZftIyDW/XZpktXXdMOuN1IxMoVmaofcIqEB6kBV....\", created_at: \"2014-04-05 21:42:09\", updated_at: \"2014-04-05 21:43:25\", account_id: 9}"

You can eval and get back the hash if you modify your string to the format above. Refer to my three line example above.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM