views:

49

answers:

3

I'm creating an AuditLog observer that watches over several models.

I'd like the observer to have an after_create, which creates a JSON object that is stored in a database column. It will contain data like {photoid:123, photoname: "asdasd", creator_id: "asdasd"} etc...

In Rails, how do I create this type of JSON object and then how do I insert it into the DB along with other non-JSON fields?

Thanks

A: 

Take a look at this: http://github.com/laserlemon/vestal_versions

If it's not what you're looking for, it will at least show you it's done.

Coderama
The auditlog is just an example to make the question easier to digest... Thanks though.
AnApprentice
+1  A: 

First, definitely check out ActiveRecord serialize and see if it does what you need: http://api.rubyonrails.org/classes/ActiveRecord/Base.html#method-c-serialize

However, if you need JSON specifically (serialize uses YAML by default), then you can always fake it by hand.

You can simply build a hash in Ruby and then call to_json on it before assigning it to your model attribute.

data = { 'photoid' => 123, 'photoname' => "asdasd", 'creator_id' => "asdasd" }
myrecord.stored_data = data.to_json
myrecord.save
tfe
Thanks, I'll try this out.
AnApprentice
Is to_json safe? I've seen some posts on Google Searches that mention it sometimes fails? Any thoughts on that?
AnApprentice
There are some wrinkles when you're using `to_json` on an activerecord object (you're supposed to use `as_json` or something), but for serializing a simple hash it's really straightforward JSON encoding... not much to go wrong. What did you find with Google?
tfe
What is the myrecord.stored_data all about ? (stored_data)?
AnApprentice
Turns out the above doesn't work...getting errors on "stored_data" does not exist... Also, should the observer be in the CONTROLLERS or MODELS Directory? bec running the generator put it in the models dir.
AnApprentice
"undefined method `save' for nil:NilClass"
AnApprentice
Getting: "undefined method `data=' for nil:NilClass" when I try this: data = { 'photoid' => 123, 'photoname' => "This is my photo", 'creator_id' => "1" } @AuditLog.data = data.to_json @AuditLog.save
AnApprentice
`stored_data` is an example attribute name. It can be anything you want. It also has to be backed by a text column in your database... it's not magic. Create a migration to add it.
tfe
+1  A: 

Just today I answered a similar (if not same) question - http://stackoverflow.com/questions/3827851/raisl-3-howto-storing-unstructured-data-in-a-database-column-field-data/3833003#3833003

pawien
@pawien thanks, that's interesting but not sure if it solves wanting to save a @AuditLog record in the observer after_create?
AnApprentice
well, I'm little bit lost on that comment. In the example it is used in the after save callback. It would be dead simple to change it to after_create. Or into the generic (shared) observer: http://guides.rubyonrails.org/active_record_validations_callbacks.html#sharing-observers. The AuditLog.audit method is generic and you can pass any model to it.
pawien