Search code examples
ruby-on-railsjsonactiverecordruby-on-rails-4.2openstruct

Rails 4 overwrite ActiveRecord Model variables after init


I store somewhat large JSON strings as text fields in my model but would like to have the data accessible as an OpenStruct variable when the instance of the model is initialized.

In other words:

Model: CrawlCache
Field: results, type: text #Storing a JSON String

When I run crawl = CrawlCache.find(x) I'd like crawl.results not to be the string but rather the result of JSON.parse(crawl.result, object_class: OpenStruct)

My code so far is this:

  after_initialize :set_results


  def set_results
    self.results = JSON.parse(self.results, object_class: OpenStruct)
  end

However when I run the aforementioned crawl = CrawlCache.find(x), crawl.results.class is still a String.

The reason I'd like to overwrite the orignial is for memory reasons, the strings are fairly large and I wouldn't want to have the string in memory AND the parsed object. That is why am not going the attr_accessor route and naming it something else.


Solution

  • Rails allows you to serialize and deserialize objects such as JSON without any additional effort or code. You can simply add this to your model:

    class CrawlCache
      serialize :results, JSON
    

    Now when you save the object it will serialize the JSON and when you call the column you can access it you would an object.

    http://api.rubyonrails.org/classes/ActiveRecord/AttributeMethods/Serialization/ClassMethods.html

    This will achieve what you want without having to add custom callbacks to your model.