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
Best Way in MySQL or Rails to Get Avg Per Day Within a Specific Date Range
Using an Alias Column in the Where Clause in Ms-SQL 2000
How to Create an Index for Elements of an Array in Postgresql
Simple SQL Select from 2 Tables (What Is a Join)
How to Store Decimal Values in SQL Server
How to Use a Package Constant in SQL Select Statement
Sql: Sum 3 Columns When One Column Has a Null Value
Standard SQL Boolean Operator Is VS. Equals (=) Operator
Executing SQL Server Agent Job from a Stored Procedure and Returning Job Result
How to Find Left Outer Join or Right Outer Join with Oracle Join (+)
Query to Order by the Number of Rows Returned from Another Select