Property and Type unification in 1.0.0.rc

29 views
Skip to first unread message

Piotr Solnica

unread,
May 25, 2010, 4:49:25 PM5/25/10
to DataMapper
Hey everyone,

With DataMapper 1.0.0.rc series you've probably noticed that Property/
Type API
has been significantly changed. In order to simplify the code we
decided to
unify Property and Type, which means that all the functionality of
Type has been
moved to Property and Type will be completely removed for 1.0.0 final.
Another
important change was creating a Property class hierarchy to cover all
the common
primitive classes that every adapter have to support. You can see the
hierarchy
in this gist: https://gist.github.com/5a99710131190c128f6e. This
means that
things like validating options or typecasting have been moved to all
the
subclasses which results in a much cleaner code organization. Here are
the most
important advantages of the refactor:

1) Each Property class has a set of predefined options with default
values that
are used in case you don't provide them when you're declaring a
property on a
model

2) Options are inheritable. For instance, if you create CustomString <
String
property then the length option will be inherited from String and set
to 50
*but* you can still override it when creating a property on a model:

User.property :name, CustomString, :length => 100

3) You can declare what options are valid for your Property via
Property.accept_options method, for instance:

module DataMapper
class Property
class CustomString < String
accept_options :foo, :bar

foo 'bazinga!' # this creates a default value for the foo option
end
end
end

So now when you do:

User.property :name, CustomString

It'll set the foo option to "bazinga!" by default

4) Typecasting to primitive has been extracted to
Property#typecast_to_primitive
- this means you don't need to worry about nil values or do checks if
the value
is already a primitive because this is handled by Property#typecast.
Example:

module DataMapper
class Property
class Settings < Object
primitive ActiveSupport::HashWithIndifferentAccess

def typecast_to_primitive(value)
ActiveSupport::HashWithIndifferentAccess.new(value)
end
end
end
end

5) Primitive can be set to any class, there's no frozen PRIMITIVES
constant
anymore

Deprecated custom types should still work and you should just get
deprecation
warnings; however, please do update them as soon as possible as with
DataMapper
1.0 final Type will go away. Here are some basic information you need
to know:

1) Every custom property has to inherit from
DataMapper::Property::Object or one
of its descendants (like Integer, String etc.)

2) If your custom property has the same primitive as one of the "core"
properties (the ones from dm-core Property hierarchy) then it should
inherit
from one of them

3) When setting up a property you can still implement bind method, but
keep in
mind it's no longer a class method (you can take a look at
Discriminator for an
example) and you can always override initialize and do your stuff
there

4) Important: remember that you need to prefix class names with "::"
when
referring to classes that are also defined in DataMapper::Property!

Here is an example of a converted CheckedInteger type (comes from
http://github.com/xaviershay/dm-checked-types) with some comments:

http://gist.github.com/413050

Please let me know if you find any issues or problems with the
upgrade. I'm
pretty sure I forgot about something so feel free to ask as many
questions as
you want :)

Cheers!

// solnic

Dan Kubb (dkubb)

unread,
May 27, 2010, 6:08:09 PM5/27/10
to DataMapper
Piotr,

Thanks so much for your work on this. I think it greatly simplifies
creation of new properties, as well as provides more control for
people writing custom properties. It's also awesome that we can
specify new options for the DSL, and have them handled by the property
subclasses.

I hope this encourages more people to use custom properties in their
DataMapper models, as well as extend some of the built-in properties
to do things that previously would've required patching dm-core.

--

Thanks,

Dan

Reply all
Reply to author
Forward
0 new messages