Forum: Ruby on Rails Exploring ActiveRecord::Base#serialize

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
B780ee0ee1480454a85df58536702f63?d=identicon&s=25 Alder Green (Guest)
on 2006-05-10 08:22
(Received via mailing list)
Hi

I was recently taught about the useful ActiveRecord::Base#serialize.
It's very useful for persisting arbitrary objects through the regular
database. For example, say you want to store a Set of all the years a
Convention took place. You do:

class Convention < ActiveRecord::Base
  serialize :years, Set
end

This effectively creates a Convention#years attribute, which is a set:
you can add items (years) to it, check if a certain year is contained
(included?) within, etc.

Generally wonderful. But there's a deficiency: when you instantiate

con = Convention.new

con.years would be nil. Trying to rely in any way on con.years' Set
properties would fail, since until you explicitly do

con.years = Set.new

the Set is simply not there. This could lead to many bugs if you
forget to assign a set to con.years. Common calls like "con.years <<
2001" and "con.years.include? 2002" would raise exceptions.

So generally, I think everyone using "serialize :foo, Set" would want
to have also:

class Convention < ActiveRecord::Base
  ...

  def after_initialize
    self.years = Set.new
  end
end

Maybe there should be some automagic way to do this?  Seeing that the
the after_initialize flows from the serialize call, that even looks
like a DRY violation. Also, it's somewhat obscure: the self.years=
syntax isn't newbie-obvious, and after_initialize doesn't appear in
the Rails method glossary [1].

To sum up, I think there should be a feature request.

-Alder

[1] http://api.rubyonrails.com/fr_method_index.html
24d2f8804e6bb4b7ea6bd11e0a586470?d=identicon&s=25 Jeremy Kemper (Guest)
on 2006-05-10 18:21
(Received via mailing list)
On May 9, 2006, at 11:21 PM, Alder Green wrote:
> you can add items (years) to it, check if a certain year is contained
> (included?) within, etc.

Yup: the second arg is an optional type restriction, not a default
value.


> forget to assign a set to con.years. Common calls like "con.years <<
> 2001" and "con.years.include? 2002" would raise exceptions.

This is a poor situation. Also consider

   A = Struct.new(:a, :b, :c)
   class Foo < AR::Base
     serialize :bar, A
   end

Automatically setting bar = A.new would fail since it needs params.
We need a default value in addition to the type condition.

   class Foo < AR::Base
     serialize(:bar) { |foo| foo.bar = A.new(1,2,3) }
   end

> To sum up, I think there should be a feature request.

Would you file one?  http://dev.rubyonrails.org/newticket

Best,
jeremy
B780ee0ee1480454a85df58536702f63?d=identicon&s=25 Alder Green (Guest)
on 2006-05-11 16:54
(Received via mailing list)
On 5/10/06, Jeremy Kemper <jeremy@bitsweat.net> wrote:
> > This effectively creates a Convention#years attribute, which is a set:
> >
>
>   end
>
> > To sum up, I think there should be a feature request.
>
> Would you file one?  http://dev.rubyonrails.org/newticket

Submitted!

http://dev.rubyonrails.org/ticket/5049

> Best,
> jeremy
> _______________________________________________
> Rails mailing list
> Rails@lists.rubyonrails.org
> http://lists.rubyonrails.org/mailman/listinfo/rails
>

Thanks for your comments and the efforts you and the other Rails-core
members make to ensure Rails is such a wonderful framework to use.

-Alder
This topic is locked and can not be replied to.