hash keys, symbolize_keys and sintrigify_keys

Hey guys,

I had recently a very weird experience. I have a Loader class that run’s a lot of different things on Active Record objects. One thing this loader does, is to preload data based on each classes settings. so basically:

scope.preload(preloads)

scope has a collection of Active Record objects.

preloads has an array with hashes inside that show what information to preload for each relation.

Preloads use to be a function inside the loader class that calculated that array, but it needed some information of the class itself, so I refactored it out into another class.

This is an example how the code works, the implementation is not very important and I simplified it for the sake of the example:

Class Incident

def preloads

calculate preloads

end

def load

Loader.new(preloads)

end

end

Class Loader < Struct.new(:preloads)

def initialize(opts = {})

self.preloads = opts[:preloads] || []

end

def load

scope.preload(preloads)

end

end

So before the preloads when inside of the loader class return something like(Every key is a symbol):

[{:updated_by_user=>[]}, {:service=>[{:account=>:additional_fields}, {:service_customers=>{:customer=>[]}}]}, {:owner=>[]}, {:closed_by_user=>[]}, {:assigned_user=>[]}, {:beetil=>{:satisfaction_ratings=>[]}}, {:beetil=>{:additional_values=>:additional_field}}, {:beetil=>{:additional_values=>:additional_field}}, :priority, :priority, :service_activity_type, {:beetil=>{:customer_beetils=>{:customer=>[]}}}, {:beetil=>:audit_trail_groups}, {:beetil=>:latest_audit_trail_group}, :incident_status, :received_by_user, {}, {}]

And when passed as an argument is transformed into(Every key is a string):

[{“updated_by_user”=>[]}, {“service”=>[{“account”=>:additional_fields}, {“service_customers”=>{“customer”=>[]}}]}, {“owner”=>[]}, {“closed_by_user”=>[]}, {“assigned_user”=>[]}, {“beetil”=>{“satisfaction_ratings”=>[]}}, {“beetil”=>{“additional_values”=>:additional_field}}, {“beetil”=>{“additional_values”=>:additional_field}}, :priority, :priority, :service_activity_type, {“beetil”=>{“customer_beetils”=>{“customer”=>[]}}}, {“beetil”=>:audit_trail_groups}, {“beetil”=>:latest_audit_trail_group}, :incident_status, :received_by_user, {}, {}]

But the problem is then I get an error of the load function saying:

TypeError: Cannot visit String

After I googled a little bit and debugged I realized that it worked with the keys as symbols and not as strings.

How weird is that? so load only accepts keys with symbols and not strings? is this a rails bug? am I approaching this wrong?

Any input would be appreciated.

all the best,

Andre