Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: 843ed2cf62
Fetching contributors…

Cannot retrieve contributors at this time

99 lines (79 sloc) 3.593 kb
layout title body_id created_at
default
Working with Legacy Schemas
docs
Fri Sep 10 16:37:37 GMT 2010

{{ page.title }}

DataMapper has quite a few features and plugins which are useful for working with legacy schemas. We're going to introduce the feature available in the core first, before moving on to plugins. Note that whilst the title is "{{page.title }}", really this applies to any situation where there is no control over the 'table' in the data-store. These features could just as easily be used to modify the fields returned by a RESTful webservice adapter, for example.

Small Tweaks

If the number of modifications are small—just one table or a few properties—it is probably easiest to modify the properties and table names directly. This can be accomplished using the :field option for properties, :child_key (or :target) for relationships, and manipulation of storage_names[] for models. In all the following examples, the use of the :legacy repository name assumes that it is some secondary repository that should behave in the special manner. If it is the main database the application will be interacting with, :default makes a much more sensible choice. Note that for the below snippet to work, you need to have have the :legacy repository set up properly.

{% highlight ruby linenos %} class Post include DataMapper::Resource

# set the storage name for the :legacy repository storage_names[:legacy] = 'tblPost'

# use the datastore's 'pid' field for the id property. property :id, Serial, :field => 'pid'

# use a property called 'uid' as the child key (the foreign key) belongs_to :user, :child_key => [ :uid ] end {% endhighlight %}

Changing Behaviour

With one or two models, it is quite possible to tweak properties and models using :field and storage_names. When there is a whole repository to rename, naming conventions are an alternative. These apply to all the tables in the repository. Naming conventions should be applied before the model is used as the table name gets frozen when it is first used. DataMapper comes with a number of naming conventions and custom ones can be defined:

{% highlight ruby linenos %}

the DataMapper model

class Example::PostModel end

this is the default

DataMapper.repository(:legacy).adapter.resource_naming_convention = DataMapper::NamingConventions::Resource::UnderscoredAndPluralized Example::PostModel.storage_name(:legacy)

=> example_post_models

underscored

DataMapper.repository(:legacy).adapter.resource_naming_convention = DataMapper::NamingConventions::Resource::Underscored Example::PostModel.storage_name(:legacy)

=> example/post_models

without the module name

DataMapper.repository(:legacy).adapter.resource_naming_convention = DataMapper::NamingConventions::Resource::UnderscoredAndPluralizedWithoutModule Example::PostModel.storage_name(:legacy)

=> post_models

custom conventions can be defined using procs, or any module which

responds to #call. They are passed the name of the model, as a string.

module ResourceNamingConvention def self.call(model_name) 'tbl' + DataMapper::Inflector.classify(model_name) end end

DataMapper.repository(:legacy).adapter.resource_naming_convention = ResourceNamingConvention Example::PostModel.storage_name(:legacy)

=> 'tblExample::PostModel'

{% endhighlight %}

For field names, use the field_naming_convention menthod. Field naming conventions work in a similar manner, except the #call function is passed the property name.

Jump to Line
Something went wrong with that request. Please try again.