How can I store a hash in my database?
Solution 1
You can use serialization with 3 options: Marshal in binary format, YAML and JSON human-readable formats of data store.
Once you are trying each of methods, do not forget to measure time to serialize and deserialize as well. If you need to pull data back in origin format, JSON is the good choice to use, because you don't need to deserialize it, but use it as a string itself.
Solution 2
Rails 4 adds support for the Postgres hstore
data type which will let you add hashes directly into your (postgres) database.
If you are using Rails 4 and Postgres, you can use hstore
in your migration:
def up
execute "create extension hstore"
add_column :table, :column, :hstore
end
def down
remove_column :table, :column
end
That execute command will enable hstore in Postgres, so you only have to do that once.
This will enable you to store a hash in :column
just like you would any other data type.
Solution 3
There are two ways to do this:
- Serialize your hash and store it in a text field.
- Split the hash and store each key in a separate row.
The problem with the first approach is that finding and manipulating is difficult and expensive. For example, prefix a "0" before the telephone number of all employees working in Foo Inc. will be a nightmare, compared to storing the data in regular tabular format.
Your schema would be:
employees (id, created_at, updated_at)
employee_details (id, employee_id, key, value)
So, to store
"company" => "Foo Inc",
"telephone" => "555-5555"
you would do:
employees: 1, 2012-01-01, 2012-01-01
employee_details (1, 1, "company", "Foo Inc"), (2, 1, "telephone", "555-5555")
Drawbacks of this approach: Rails does not natively support such kind of a schema.
Solution 4
You're looking for serialization. It will help you to do exactly what you want.
Solution 5
Rails 4 has a new feature called Store, so you can easily use it to solve your problem. You can define an accessor for it and it is recommended you declare the database column used for the serialized store as a text, so there's plenty of room. The original example:
class User < ActiveRecord::Base
store :settings, accessors: [ :color, :homepage ], coder: JSON
end
u = User.new(color: 'black', homepage: '37signals.com')
u.color # Accessor stored attribute
u.settings[:country] = 'Denmark' # Any attribute, even if not specified with an accessor
# There is no difference between strings and symbols for accessing custom attributes
u.settings[:country] # => 'Denmark'
u.settings['country'] # => 'Denmark'
Related videos on Youtube
jpw
Updated on July 21, 2022Comments
-
jpw almost 2 years
Is there a Ruby, or Activerecord method that can write and read a hash to and from a database field?
I need to write a web utility to accept POST data and save it to a database, then later on pull it from the database in its original hash form. But ideally without 'knowing' what the structure is. In other words, my data store needs to be independent of any particular set of hash keys.
For example, one time the external app might POST to my app:
"user" => "Bill", "city" => "New York"
But another time the external app might POST to my app:
"company" => "Foo Inc", "telephone" => "555-5555"
So my utility needs to save an arbitrary hash to a
text
field in the database, then, later, recreate the hash from what was saved. -
courtsimas about 9 yearsdoes it support nested hashes/json?