0

I have setup the following model with specific parent and child keys:

class Province
  include DataMapper::Resource

  property :name_short, String, key: true, length: 2, unique: true
  property :name_long,  String, length: 1..50

  has n, :municipalities, 'Municipality',
    parent_key: [:name_short],
    child_key: [:province]
end

class Municipality
  include DataMapper::Resource

  property :province,            String, key: true, length: 2
  property :name,                String, key: true, length: 1..40
  property :lat,                 Float
  property :long,                Float

  property :current_population,  Integer

  belongs_to :province, 'Province',
    parent_key: [:name_short],
    child_key: [:province]

end

I create the associated records with:

        province = Province.get('BC')
        municipality = province.municipalities.new(
          name: '100 mile house',
          lat: 51.23131,
          long: 121.65489,
          current_population: 0)

Then execute municipality.save, which fails because the record it is trying to save (see below) is trying to use the entire Province object as the key, instead of just the :name_short field.

#<Municipality @province=#<Province @name_short="BC" @name_long="British Columbia"> @name="100 mile house" @lat=51.64300975 @long=121.295022 @current_population=0>

What am I doing wrong?

The save error returned is a validation type error:

["Province must be at most 2 characters long", "Province must be of type String"]

Hmmm. Taking another look at this I'm wondering if perhaps DataMapper doesn't enforce referential integrity (by inserting the parent key into the new child) itself, and that I probably have to do this by setting the Province field in Municipality myself? I'll give that a try in a bit... nope,that didn't fix it.

UPDATE: Strange, but by adding the following to_s method to the Province class, I got rid of the "Province must be at most 2 characters long" error - but still get the String error:

def to_s
  @short_name
end
Gus Shortz
  • 1,711
  • 1
  • 15
  • 24

1 Answers1

0

Alright, it seems one shouldn't name your key properties the same as your associated classes (thanks to a member of the DataMapper Google Group for pointing me in the right direction).

By renaming all :province properties to :prov, and changing all :province key references, in the belongs_to and has n declarations, to :prov, it seems to work now.

I am also saving using p = Province.get('ON')/m = Municipality.new(...) and p.municipalities << m, followed with a p.save (not sure whether I should be using p.municipalities.save instead).

NOTE: I'm using p.municipalities.save and everything works.

Gus Shortz
  • 1,711
  • 1
  • 15
  • 24