has_sparse_attributes is an extension for ActiveRecord that allows key/value attributes to be added to a model. The key/value attributes are then stored using one of the available storage options. Current storage engines include column storage using ActiveRecord’s serialize method and table storage where each attribute is a row.
:storage
- :column
or :table
(required)
:serialize
- set to true to serialize all values before they are stored in the database (YAML is used for serialization), all values are stored as strings if false
:column_name
- the name of the column where the attributes will be stored
:attribute_class_name
- the name of the attribute key/value class, defaults to SparseAttribute
:table_name
- the name of the table where the key/value records are stored
:id_column
- the name of the unique id column in the table
create_table :guitars do |t| t.string :brand, :limit => 255 t.string :model, :limit => 255 t.integer :strings, :default => 6 t.text :sparse_attributes end
class Guitar < ActiveRecord::Base has_sparse_attributes([:weight, :color, :year], :storage => :column) end
x = Guitar.new() x.color = 'Green' x.save
create_table :guitars do |t| t.string :brand, :limit => 255 t.string :model, :limit => 255 t.integer :strings, :default => 6 end
create_table :guitar_sparse_attributes do |t| t.references :guitar t.string :name, :limit => 255 t.string :value, :limit => 1024 end add_index :guitar_sparse_attributes, [:guitar_id, :name], :unique => true
class Guitar < ActiveRecord::Base has_sparse_attributes([:weight, :color, :year], :storage => :table) end
x = Guitar.new() x.color = 'Green' x.save puts x.color
Attributes are serialized as YAML and stored in a column using the ActiveRecord serialize method.
-
Add/Update/Delete - Requires one SELECT query to retrieve the existing attributes and one INSERT/UPDATE query to write the attributes.
Operations are not atomic, sparse attributes may be lost if multiple saves occur simultaneously for the same record. Versioning will be added as an option in the future to resolve this.
Attributes are stored in a key/value table where each attribute is one row.
-
Add - One SELECT to search for an existing attribute and one INSERT to add the record (for each key/value pair)
-
Update - One UPDATE query per key/value pair, if the record id has changed there is an additional SELECT & UPDATE required
-
Delete - One DELETE if the record id has not changed since it was read from the database, two DELETE queries if the id has changed
Run: ruby test/sparse_attributes.rb
Copyright © 2010-2019 Edward Potocko, released under the MIT license.