rubydatamapperruby-datamapper

How to make a Many-To-One relationship in DataMapper


I'm trying to create an association between two models:

class Person
   include DataMapper::Resource
   property :id, Serial
   property :name, String
end

class Country
   include DataMapper::Resource
   property :id, Serial
   property :name, String
end

I just need a simple relationship on Person (a country_id).

My first idea was to put a has 1 property on Person:

class Person
   include DataMapper::Resource
   property :id, Serial
   property :name, String
   has 1, :country
end

Instead of a country_id on Person table, Datamapper created a person_id on Country.

To get what I need, I had to make it inverse:

class Country
   include DataMapper::Resource
   property :id, Serial
   property :name, String
   has 1, :person
end

This way I got my country_id field on Person table, but it really doesn't make any sense for me.

Am I misunderstanding something or is there another way to make this association?


Solution

  • Whenever Model A "has" Model B (either one or many), you add the foreign key to Model B.

    The flipside of this is "belongs to" - that's what you put on the Model with the foreign key.

    I guess in DataMapper you don't have to add foreign key columns explicitly, but you could still do it if you want.

    # Person
    property :country_id, Integer
    

    Since the foreign key in on Person, you'd use "belongs to". It seems like the same thing as "has one", but it's not. You generally only need "has one" in special cases like one-to-one relationships.

    # Person
    belongs_to :country
    
    # Country
    has n, :people
    # you could use has 1, :person if for some reason every country
    # only had 1 person in it