Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Move the serializing activerecord article to update the date

  • Loading branch information...
commit e58fc446887a6c42c225347b33746563ecec03f6 1 parent ce10ee0
Jeff Kreeftmeijer authored
92 source/_posts/2011-03-09-serializing-activerecord-attributes-with-arbitrary-objects.markdown
Source Rendered
... ... @@ -0,0 +1,92 @@
  1 +---
  2 +title: "Serializing ActiveRecord Attributes with Arbitrary Objects"
  3 +author: "Jeff Kreeftmeijer"
  4 +categories:
  5 + - "what-s-new-in-edge-rails"
  6 +---
  7 +
  8 +<span class="version">**Rails** 3.1</span>
  9 +
  10 +As you might know already, ActiveRecord lets you store serialized objects by using `serialize` in your model:
  11 +
  12 +<div class="code_window">
  13 +<em>Ruby - app/models/user.rb</em>
  14 +{% highlight ruby %}
  15 + class User < ActiveRecord::Base
  16 + serialize :interests
  17 + end
  18 +{% endhighlight %}
  19 +</div>
  20 +
  21 +These serializeable attributes can then be set as any Ruby type such as an array:
  22 +
  23 +<div class="code_window">
  24 +<em>rails console</em>
  25 +{% highlight ruby %}
  26 +user = User.create!(:interests => ['dinosaurs', 'lasers'])
  27 +user.reload.interests # => ["dinosaurs", "lasers"]
  28 +{% endhighlight %}
  29 +</div>
  30 +
  31 +Under the hood, this array is automatically converted to YAML. You won't notice this unless you check what's being inserted into your database:
  32 +
  33 +<div class="code_window">
  34 +<em>log/development.log</em>
  35 +{% highlight sql %}
  36 +INSERT INTO "users" ("updated_at", "interests", "created_at") VALUES ('2011-03-05 13:14:05.054192', '---
  37 +- dinosaurs
  38 +- lasers
  39 +', '2011-03-05 13:14:05.054192')
  40 +{% endhighlight %}
  41 +</div>
  42 +
  43 +### Using arbitrary objects
  44 +
  45 +Aaron Patterson recently did some work for Rails 3.1 which allows you to use arbitrary objects to serialize your attributes, all they need to do is respond to `load` and `dump`. This allows you to specify a custom encoding for your models `serialize` fields. For example, here is what a Base64 encoding might look like:
  46 +
  47 +<div class="code_window">
  48 +<em>Ruby - app/models/user.rb</em>
  49 +{% highlight ruby %}
  50 +class User < ActiveRecord::Base
  51 + class Base64
  52 + def load(text)
  53 + return unless text
  54 + text.unpack('m').first
  55 + end
  56 +
  57 + def dump(text)
  58 + [text].pack 'm'
  59 + end
  60 + end
  61 +
  62 + serialize :bank_account_number, Base64.new
  63 +end
  64 +{% endhighlight %}
  65 +</div>
  66 +
  67 +Just like the default YAML serialization, ActiveRecord won't bother you with any serialized data, unless you check the SQL query:
  68 +
  69 +<div class="code_window">
  70 +<em>rails console</em>
  71 +{% highlight ruby %}
  72 +user = User.create!(:back_account_number => "0000001 00000011 0000001 00000011")
  73 +user.reload
  74 +user.bank_account_number # => "0000001 00000011 0000001 00000011"
  75 +{% endhighlight %}
  76 +</div>
  77 +
  78 +<div class="code_window">
  79 +<em>log/development.log</em>
  80 +{% highlight sql %}
  81 +INSERT INTO "users" ("updated_at", "back_account_number", "created_at") VALUES ('2011-03-05 17:12:01.459862', 'MDAwMDAwMSAwMDAwMDAxMSAwMDAwMDAxIDAwMDAwMDEx\n', '2011-03-05 17:12:01.459862')
  82 +{% endhighlight %}
  83 +</div>
  84 +
  85 +Just remember, YAML serialization is still used by default, but creating your own serialization object is as simple as `load` and `dump`.
  86 +
  87 +####Links:
  88 +
  89 +[Custom serialization in action video](http://www.youtube.com/watch?v=7cco1jxori8)
  90 +
  91 +The Rails commits [here](https://github.com/rails/rails/commit/3cc2b77dc1cb4c1e5cfac68c7828e35a27415e0d) and [here](https://github.com/rails/rails/commit/ebe485fd8ec80a1a9b86516bc6f74bc5bbba3476)
  92 +

0 comments on commit e58fc44

Please sign in to comment.
Something went wrong with that request. Please try again.