0

The specific instance I am referring to is here. I want to use a row from the Grid table to be the value of the Grid property in the Driver table. But I cannot get updates in the Grid table to persist through to the Grid property on the Driver table I want to use a row from the Race table to be the value of the Race property in the Driver table.

Here is the code for the datamapper stuff.

require "rubygems"
require "json"
require "sinatra"
require "sinatra/reloader"
require "sqlite3"
require "data_mapper"

DataMapper::setup(:default, "sqlite3://#{Dir.pwd}/season.db")


class Driver
    include DataMapper::Resource
    property :id, String, :key => true
    property :ptd, Integer
    property :races, Integer
    property :grid, Object
    property :race, Object
    property :hcScore, Integer
    property :domScore, Integer
end

class Grid
    include DataMapper::Resource
    property :id, String, :key => true
    property :AUS_Q, Integer
    property :MAL_Q, Integer
    property :CHI_Q, Integer
    property :BAH_Q, Integer
end

class Race
    include DataMapper::Resource
    property :id, String, :key => true
    property :AUS_R, Integer
    property :MAL_R, Integer
    property :CHI_R, Integer
    property :BAH_R, Integer
end

class Team

    include DataMapper::Resource
    property :id, String, :key =>  true
    property :domScore, Integer
    property :drivers, Object
end

DataMapper.finalize.auto_migrate!

In irb I will do something like

irb(main):001:0> require "./season.rb"
=> true
irb(main):002:0> v = Driver.create id: "VET"
=> #<Driver @id="VET" @ptd=nil @races=nil @grid=nil @race=nil @hcScore=nil @domScore=nil>
irb(main):003:0> g = Grid.create id: "VET"
=> #<Grid @id="VET" @AUS_Q=nil @MAL_Q=nil @CHI_Q=nil @BAH_Q=nil>
irb(main):004:0> v.grid = Grid.get "VET"
=> #<Grid @id="VET" @AUS_Q=nil @MAL_Q=nil @CHI_Q=nil @BAH_Q=nil>
irb(main):005:0> v.save
=> true
irb(main):006:0> g.update(:AUS_Q => 6)
=> true
irb(main):007:0> v
=> #<Driver @id="VET" @ptd=nil @races=nil @grid=#<Grid @id="VET" @AUS_Q=nil @MAL_Q=nil @CHI_Q=nil @BAH_Q=nil> @race=nil @hcScore=nil @domScore=nil>
irb(main):008:0> Grid.get "VET"
=> #<Grid @id="VET" @AUS_Q=6 @MAL_Q=nil @CHI_Q=nil @BAH_Q=nil>
irb(main):009:0> AUS_Q = 6 in the Grid table but in the Driver table it continues to be nil!

As you can see - AUS_Q in the Driver table continues to be nil even though I set it to be 6 in the Grid table.

Chances are I am doing it wrong and there is an easier way to do this. I encourage all corrections and smackdowns.

JoeyC
  • 550
  • 9
  • 19

1 Answers1

1

I would suggest that you use belongs_to to create association between resources, and that you use an identity map, like this:

require "sqlite3"
require "data_mapper"

class Driver
    include DataMapper::Resource
    property :id, String, :key => true
    belongs_to :grid, :required => false
end

class Grid
    include DataMapper::Resource
    property :id, String, :key => true
    property :AUS_Q, Integer
end

DataMapper::setup(:default, "sqlite3://#{Dir.pwd}/season.db")
DataMapper.finalize.auto_migrate!

DataMapper.repository(:default) do
  v = Driver.create id: "VET"
  g = Grid.create id: "VET"
  v.grid = Grid.get "VET"
  v.save
  g.update(:AUS_Q => 6)
  puts v.grid.AUS_Q
  puts Grid.get("VET").AUS_Q
end

Everything you do within the block initiated by DataMapper.repository(:default) do will use an identity map. Thus, identical objects in the database will result in identical objects in memory.

Adiel Mittmann
  • 1,732
  • 9
  • 12
  • When you use a belongs_to doesn't it need a subsequent has n on the table it is linking to? Also, what is the advantage of making this association. I cannot see how the DataMapper.repository block would use this relationship. – JoeyC May 08 '12 at 23:34
  • 1
    You add `has n` to the other table only if you need. The advantage of making the association is that you're mapping a real association (which actually exists) to a DM association, thus taking full advantage of DM. That block is there to make sure that identical objects in the database correspond to identical objects in memory -- which means that when you change `AUS_Q` in a `Grid` object, a `Driver` object associated to it will see the change. – Adiel Mittmann May 09 '12 at 14:11
  • This is a good answer. Sorry it took me so long to come back to it! – JoeyC Jan 10 '13 at 22:56