Serialize Nested Hash Problem!

Hi,

I am serializing an attribute in my model with serialize :data

The data in question is a hash defined as

{:terminal_id => terminal_id, :order_data => table_order_data, :table_id => table_id}

I have deployed my app on a few machines and it works well, storing the data above in serialized format as follows:

Hi,

I am serializing an attribute in my model with serialize :data

The data in question is a hash defined as

which is different to the above (which actually worked for me)

I am not sure what is going on, as I am using the exact same codebase.

The difference is that you now cannot use strings and symbols interchangeably as keys for this hash. The most common way to come across such hashes (other than creating them explicitly) is via the params hash (and its subhashes) which are always HashWithIndifferentAccess instances Are you saying that you did a deploy that did not change a single line of code in the entire app (and there were not changes in version of the various gems you might use) ?

What does the code that sets this hash look like?

Fred

Hi Fred, thanks for your feedback.

Yes, the data contained in the subhash (table_order_data) comes directly from the params hash.

In which case I am not in control of how that hash is built.

This leads me to think that it has got something to do with how the params hash is constructed, rather than my application code?

"Are you saying that you did a deploy that did not change a single line

of code in the entire app (and there were not changes in version of

the various gems you might use) ?"

Yes, I have the same codebase deployed on a different machine that is running apache and passenger. The gems are not exactly the same, which could be the problem.

Here is a list of the gems that are on the working machine:

abstract (1.0.0) actionmailer (3.0.5) actionpack (3.0.5) activemodel (3.0.9, 3.0.5) activerecord (3.0.5) activeresource (3.0.5) activesupport (3.0.9, 3.0.5) annotate-models (1.0.4) archive-tar-minitar (0.5.2) arel (2.0.9) builder (2.1.2) bundler (1.0.12) columnize (0.3.2) daemons (1.0.10) erubis (2.6.6) faker (0.9.5) gem_plugin (0.2.3) i18n (0.5.0) linecache19 (0.5.12, 0.5.11) mail (2.2.19, 2.2.15) meta_search (1.0.5) mime-types (1.16) mongrel (1.2.0.pre2) mysql2 (0.2.6) polyglot (0.3.1) populator (1.0.0) rack (1.2.2) rack-mount (0.6.14) rack-test (0.5.7) rails (3.0.5) railties (3.0.5) rake (0.8.7) ruby-debug-base19 (0.11.25, 0.11.24) ruby-debug-ide (0.4.16) ruby-debug19 (0.11.6) ruby_core_source (0.1.5, 0.1.4) test-unit (2.3.0) thor (0.14.6) treetop (1.4.9) tzinfo (0.3.27, 0.3.25) will_paginate (3.0.pre2)

and here are a list of the gems that are on the new machine where the app is not working:

abstract (1.0.0) actionmailer (3.0.5) actionpack (3.0.5) activemodel (3.0.5) activerecord (3.0.5) activeresource (3.0.5) activesupport (3.0.5) archive-tar-minitar (0.5.2) arel (2.0.9) builder (2.1.2) bundler (1.0.15) columnize (0.3.4) daemon_controller (0.2.6) daemons (1.0.10) erubis (2.6.6) faker (0.9.5) fastthread (1.0.7) gem_plugin (0.2.3) i18n (0.6.0) linecache19 (0.5.12) mail (2.2.19) meta_search (1.0.5) mime-types (1.16) mongrel (1.2.0.pre2) mysql2 (0.2.6) passenger (3.0.7) polyglot (0.3.1) populator (1.0.0) rack (1.2.3) rack-mount (0.6.14) rack-test (0.5.7) rails (3.0.5) railties (3.0.5) rake (0.9.2, 0.8.7) rmagick (2.13.1) ruby-debug-base19 (0.11.25) ruby-debug19 (0.11.6) ruby_core_source (0.1.5) thor (0.14.6) treetop (1.4.9) tzinfo (0.3.29) will_paginate (3.0.pre2)

I am not sure what gems are actually used in building the params hash or when using the “serialize” call, could you shed some light on that and maybe I can pin point what gem exactly is at the wrong version?

thanks,

Lee

I am not sure what gems are actually used in building the params hash or when using the "serialize" call, could you shed some light on that and maybe I can pin point what gem exactly is at the wrong version?

some combination of the rack and rails gems, although if you are using bundler bundler should be ensuring you always run the same versions.

Fred

Yes, I am using bundler, just that in my gemfile it states to use versions either BIGGER THAN or equal (~>) to the speicified versions, which is the reason why different versions are appearing on new systems.

I am not fully up on using bundler, is there a way to lock to specific versions of gems?

Here is my Gemfile.lock

remote: http://rubygems.org/ specs: abstract (1.0.0) actionmailer (3.0.5) actionpack (= 3.0.5) mail (~> 2.2.15) actionpack (3.0.5) activemodel (= 3.0.5) activesupport (= 3.0.5) builder (~> 2.1.2) erubis (~> 2.6.6) i18n (~> 0.4) rack (~> 1.2.1) rack-mount (~> 0.6.13) rack-test (~> 0.5.7) tzinfo (~> 0.3.23) activemodel (3.0.5) activesupport (= 3.0.5) builder (~> 2.1.2) i18n (~> 0.4) activerecord (3.0.5) activemodel (= 3.0.5) activesupport (= 3.0.5) arel (~> 2.0.2) tzinfo (~> 0.3.23) activeresource (3.0.5) activemodel (= 3.0.5) activesupport (= 3.0.5) activesupport (3.0.5) archive-tar-minitar (0.5.2) arel (2.0.9) builder (2.1.2) columnize (0.3.2) daemons (1.0.10) erubis (2.6.6) abstract (>= 1.0.0) faker (0.9.5) i18n (~> 0.4) gem_plugin (0.2.3) i18n (0.5.0) linecache19 (0.5.12) ruby_core_source (>= 0.1.4) mail (2.2.19) activesupport (>= 2.3.6) i18n (>= 0.4.0) mime-types (~> 1.16) treetop (~> 1.4.8) meta_search (1.0.5)

If I had of ran

bundle install --deployment

on the new machine, would that mean that it would not have specified dependencies as >= (which seems to be breaking the app as the newer gems are being downloaded and are incompatible with my code)

surely somebody has had this problem?

When you run bundle install --deployment it is supposed to use exactly the versions in Gemfile.lock (if you look further down in the Gemfile.lock file it lists the set of versions it picked that matched the requirements of your gemfile), so that you get exactly the same version on any machine you run it on. You can run bundle show to see what versions bundler is actually pulling in for your two versions.

This is an odd problem though - params have always been an HashWithIndifferentAccess and continue to be so - it feels to me that you must be doing something to them that causes them to revert to being normal hashes.

Fred

could it be something to do with passenger?

I have just made 100% sure that both systems are using the exact same gems, the only difference now is that I am using passenger on one system and not on the one that is working ok

the hash comes directly from the params.

I store in the serializable column the exact hash that is there, so it seems like the params hash is not an instance of HashWithIndifferentAccess in the new deployment…

why could this be?

do you have the same version of ruby?

Hi tom,

yes the versions of ruby are also identical.

I have no clue what was happening, but I am going to get around it by converting the hash to json format first then allowing it to be serialized and then retrieving it and doing a JSON.parse on it. After which I will use symbolize_keys!

I can be 100% certain then of the format of the data and should not have any problems.

thank you both for your help

how do you serialize?

via serialize :params ?

don't you have somewhere in the code this?

class HashWithIndifferentAccess < Hash   def to_yaml(opts = {})     self.to_hash.to_yaml(opts)   end end

there could be difference between env - production/devel, try to load your app as production on your localhost

I have a call

serialize :data

in the associated model.

Where exactly would I see the code you posted, and what exactly has it got to do with my problem, I don’t think I follow.

Anyway, I have solved the problem by going from params hash to json to serialized data and then parsing it back out when it is needed by doing the reverse.

thanks

I wonder if the problem could be that "data" is a reserved word in Rails. Using reserved words sometimes appears ok but then gives strange problems.

See http://oldwiki.rubyonrails.org/rails/pages/ReservedWords

Colin

that could well be the case. I will revert the code and try rename it.

I’ll get back with results, thanks