I'm not sure if I understood your question properly. But I will try to answer it anyway.
If you need to convert the model to JSON it's super simple. Just call .to_json on the model. Then you can store it the TEXT column.
To read it back you have two options:
read the value as a Ruby hash: ActiveSupport::JSON.decode(some_json_text)
read the value as an object - the original model: take the hash you got above and pass it to SomeModel.new as a parameter. But in this case you have to be careful - associated collections will not work, id will not be set, etc.
There are many options how to customize the behavior and it's not clear what's best for you. I recommend to read this help page: http://railsapi.com/doc/rails-v3.0.0/classes/ActiveModel/Serializers/JSON.html and customize your solution as appropriate.
In the following example I'm not using the .to_json method on the model as the approach in the example is much more customizable. For example you can control the behavior of associations (if they are going to be stored into the log or not), etc. Read the linked document and you'll see.
And here comes the sample implementation (read comments inside)
class AuditLog < ActiveRecord::Base
#
# Stores shallow snapshot (without nesting into associations) of current
# model into the log in the JSON form
#
def self.audit(m)
# encode passed model into the JSON text
json = ActiveSupport::JSON.encode(m)
# create new log record and store it to the database
create(:model => m.class,
:data => json)
end
#
# Returns the logged item as a Ruby hash
#
# Your can access the result with ["attribute_name"]
#
def get_as_hash
# get the hash
result = ActiveSupport::JSON.decode(self.data)
# normally the json is { model_name => { attributes ... } } and we want the
# inner hash - so let's take it
result.values.first
end
#
# Returns the logged item as an original model (like Post, Comment, etc.)
#
# Beware that associations are filled only if they are stored in audit method
# So in case of Post: post.comments will always return an empty array
#
def get_as_model
# get hash
hash = get_as_hash
# create instance of the class model and pass the hash to init
# attribute values
m = self.model.constantize.new(hash)
# the initializator above ignore :id so let's set it manually
m.id = hash[:id]
# return the model
m
end
end
And you can use it this way:
class Post < ActiveRecord::Base
has_many :comments
# after any successful change store the model to log
after_save :audit
private
# store the whole model to the log
def audit
AuditLog.audit(self)
end
end
Hope you'll enjoy it!