Pros/Cons of Storing Serialized Hash VS. Key/Value Database Object in Activerecord

Pros/Cons of storing serialized hash vs. key/value database object in ActiveRecord?

I had the same problem, but finally made the decision.

Hash serialization option makes maintenance problem. It is hard to query, extend or refactor such data - any subtle change needs migration which means reading each record deserializing and serializing back, and depending on refactoring serialization exception may happen.
I tried both binary serialization and JSON - the second is easier to extract and fix but still too much hassle.

Separate settings table is what I'm trying to use now - much easier to maintain. I plan to use Preferences gem for that which mostly does all abstraction for easy use. I'm not sure if it works with Rails 3 yet - it is small so I can extend it if needed.

Update Nov 2013

Recently released Rails 4 supports great new features of PostgreSQL 9.1+ such as hstore or json column types for your dynamic data sets. Here is an article covering hstore usage in Rails 4. Both types support indexing and advanced querying capabilities (Json with Pg 9.3). Hstore is also available to Rails 3 users with activerecord-postgres-hstore gem.

I am in the process of migrating some of non critical preference tables in my project to hstores. In migrations I just update table definitions and execute one SQL query per table to move the data.

Serializing ActiveRecord objects without storing their attributes?

As far as I understand your problem you should google for: acts_as_nested_set better_nested_set even_better_nested_set and awesome_nested_set. I know they don't store the serialized hierarchies, but you should store their nodes atomically. Even huge traffic sites do that. Other than that - you should consider NoSQL (or schema-less DB).

Serialized Hash to allow arbitrary key/value pairs

Alright, here is what I tried and it is working quite well.

User model - models/user.rb

class User < ActiveRecord::Base
serialize :settings

attr_accessible :email, :settings_attributes

def settings_attributes=(attributes)
self.settings = attributes
end
end

User controller - controllers/users_controller.rb

class UsersController < ApplicationController
def index
@users = User.all
end

def show
@user = User.find(params[:id])
end

def edit
@user = User.find(params[:id])
end

def update
@user = User.find(params[:id])
if @user.update_attributes(params[:user])
redirect_to users_path
else
render :new
end
end
end

User edit page - views/users/edit.html.erb

<h1>Users#edit</h1>

<%= form_for @user do |f| %>

<%= f.fields_for :settings_attributes, OpenStruct.new(@user.settings) do |builder| %>

<% @user.settings.keys.each do |key| %>

<%= builder.text_field key.to_sym %><br />

<% end %>

<% end %>

<%= f.submit %>

<% end %>

When updating the user, the controller receive in the params hash a key named settings_attributes. By defining a setter in our User model, we are able to edit the serialized settings attribute.

In the view we are simply looping on all the keys in the settings hash and display a textfield. You may want to display other thing such as textarea or even select. This would require to customize the settings hash in order to know what is the type of the setting you want to display (you could store a key named type in the hash which hold the type of the setting and a key value which holds the name of the setting)

Regarding the add_new_link functionality, you may want to take a look at this railscast http://railscasts.com/episodes/196-nested-model-form-revised

I fired a rails application from scratch and it's working quite well. Let me know if you have any questions.

Storing key value serialized extra fields in model (Rails)

There are some small problems with storing data in serialized fields in model. First, ActiveRecord always consider serialized fields dirty, as a result, the record in database will always be updated whenever save is called. Second, it is difficult to search the data saved in serialized fields. So I suggest adding another model ExtraValue to store those values, and making Contact has_many :extra_values. Then you can take advantage of nested forms to build your form.

Searching serialized data, using active record

Basically, you can't. The downside of #serialize is that you're bypassing your database's native abstractions. You're pretty much limited to loading and saving the data.

That said, one very good way to slow your application to a crawl could be:

MyModel.all.select { |m| m.mycode.include? 43402 }

Moral of the story: don't use #serialize for any data you need to query on.

How to store hash in session in Ruby

Serialize your Hash to a JSON or YAML string and store that. This assumes that you don't have anything crazy in your Hash like a lambda or a Thread that cannot be serialized.

How to store hash in session in Ruby

Serialize your Hash to a JSON or YAML string and store that. This assumes that you don't have anything crazy in your Hash like a lambda or a Thread that cannot be serialized.

Building a hash in RoR: use object reference or ID as key?

The true question is "how are you going to use this hash". If you need to iterate and show some information about the users, the first option is better ; if you need to access a value corresponding to a user's ID, option 2 is better. You could even think of another solution

my_hash = {}

User.all.each do |u|
my_hash[u.id] = [u, some_value]
end

My point is : there is no correct answer, it really depends on the use you're going to make of this hash.

How do I deserialize an Rails ActiveRecord serialized field on rails console?

It looks like you have a yaml object in your database. You can try the following:

YAML::load(your_column)

As an example conversion of a column with a Time object:

    [1] pry(main)> puts t.request
--- 2016-06-22 01:23:54.038830166 +03:00
...
=> nil
[2] pry(main)> YAML::load(t.request)
=> 2016-06-22 01:23:54 +0300
[3] pry(main)> YAML::load(t.request).class
=> Time


Related Topics



Leave a reply



Submit