user2775888
user2775888

Reputation: 39

save Hash to a column (type: text) in database by serialization, why is it saved YAML

We are trying to serialize an attribute called differences in order to save the value of this attribute as a Hash into database. The type of differences is text. it used to be saved as Hash in the database. But recently we found out it is saved yaml. is there any way to prevent it saving as yaml?

  Class A < ActiveRecord::Base

    has_many :bs
    serialize :differences

    def diff(other)
      b_diffs = {}
      bs.zip(other.bs).each do |a,b|
       b_diffs.merge!(:bs => a.diff?(b)
      end
    end

    def diff_against_last_a
      last_a = ....
      self.differences = last_a.diff(self)
    end
  end

Any suggestion?

EDIT: my problem is i can't retrieve differences as Hash.

Interestingly, when i check on console, it is saved as yaml, and retrieved as yaml. and then i rerun the the method diff(other) and save the result to differeces, it shows as Hash and i can retrieve Hash. But it doesn;t work this way when running on my app.

I think the problem here is the serialized data are no longer returned Hash.

UPDATE: So i found out under the development environment, there is such a problem. But in production and staging (we use heroku), it practises fine. so We'll consider it ok then.

Upvotes: 1

Views: 1451

Answers (1)

shivam
shivam

Reputation: 16506

In addition to my comment, here is the official description:

If you have an attribute that needs to be saved to the database as an object, and retrieved as the same object, then specify the name of that attribute using this method and it will be handled automatically. The serialization is done through YAML. If class_name is specified, the serialized object must be of that class on retrieval or SerializationTypeMismatch will be raised.

source: http://apidock.com/rails/ActiveRecord/Base/serialize/class

In layman's terms "When Rails serializes a hash to save in the db, all it does is convert it to YAML so that it can be stored as a string."

As the last line of official description reads, you have define the class of retrieval. Hash in your case. So declare serialize like this:

 serialize :differences, Hash

Upvotes: 2

Related Questions