Serialist

Serialize anything. Why waste time migrating your table for yet another dumb attribute you won’t search on? Add one serialization field in your table, and let serialist do the rest : validate and mass_assign all your serialized stuff, transparently. Now in version 1.0.0, fully tested.

Before!

class Article < ActiveRecord::Base
  serialize :preferences
  # impossible...
  # validates_presence_of :key
end

>> a = Article.new
>> a.preferences = {}
>> a.preferences[:key] = "value"
>> a.preferences[:key]
=> "value"
>> Article.create({:preferences => {:key => "value"}})
=> #<Article id: ##, preferences: {:key=>"value"}>

After!

class Article < ActiveRecord::Base
  serialist :preferences, [:key, :other_key, :yet_another_key]
  validates_presence_of :key
end

>> a = Article.new
>> a.key = "value"
>> a.key
=> "value"
>> Article.create!
=> "key cannot be blank"
>> Article.create({:key => "value"})
=> #<Article id: ##, preferences: {:key=>"value"}>

Install the gem!

sudo gem install serialist

Try the demo!

rails -m http://github.com/bbenezech/serialist/raw/master/installation-template.txt serialist-example

Or simply generate a migration for your existing rails app!

./script/generate serialist SerialistMigration MyModel my_serialist_attribute

Ex :

./script/generate serialist SerialistMigration Article slug
rake db:migrate

Then hook Serialist into your ActiveRecord model :

serialist :my_serialist_attribute, [:foo, :bar]
# OR
serialist :my_serialist_attribute
# See below

# Add validation as you normally would :
validates_presence_of :bar
# etc.

Serialist comes in 2 flavors!

Declarative, use define_method as your model load.

class Article
  serialist :slug, [:foo, :bar]
  validates_presence_of :foo
end

Allows you to serialize only the desired keys. ex :

./script/console
>> Article.create!
=> 'foo cannot be blank'
>> a = Article.new
=> #<Article id: nil, title: nil, created_at: nil, updated_at: nil, slug: nil>
>> a.foo?
=> false
>> a.foo
=> nil
>> a.foo = "hello"
=> "hello"
>> a.foo?
=> true
>> a.taz = "hello"
=> NoMethodError: undefined method `taz=' ...
>> a
=> #<Article id: XX, title: nil, created_at: "..", updated_at: "..", slug: {:foo=>"hello"}>

Catch-all, use define_method lazily at access time (hooked in your model method_missing)

class Article
  serialist :slug
  validates_presence_of :foo
end

Allows you to serialize anything. ex :

./script/console
>> Article.create!
=> 'foo cannot be blank'
>> a = Article.new
=> #<Article id: nil, title: nil, created_at: nil, updated_at: nil, slug: nil>
>> a.foo
=> nil
>> a.foo?
=> false
>> a.foo = "hello"
=> "hello"
>> a.foo?("hello")
=> true
>> a.foo?
=> true
>> a.foo
=> "hello"
>> a.baz?
=> false
>> a.baz
=> nil
>> a
=> #<Article id: XX, title: nil, created_at: "..", updated_at: "..", slug: {:foo=>"hello"}>

But be aware…

# Don’t use method#2 with Serialist loaded before other ActiveRecord “automagicians” plugins

# And of course don’t serialize attributes you may want to search on, or index on, or use with any other database related stuff.

# run the tests with your version of ActiveRecord (tested with rails 2.3.4) (go to the unpacked gem and simply run ‘rake’, watch for errors. Send a bug report if any, specifying you ActiveRecord or rails version, thanks)

Copyright © 2009 Benoit Bénézech, released under the MIT license