【问题标题】:How do you use a row from one table as a property in another table using Datamapper?如何使用 Datamapper 将一个表中的一行用作另一个表中的属性?
【发布时间】:2012-05-08 09:59:21
【问题描述】:

我所指的具体实例是here。我想使用 Grid 表中的一行作为 Driver 表中 Grid 属性的值。但是我无法在 Grid 表中获取更新以持续到 Driver 表上的 Grid 属性 我想使用 Race 表中的一行作为 Driver 表中 Race 属性的值。

这是数据映射器的代码。

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!

在 irb 我会做类似的事情

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!

如您所见 - Driver 表中的 AUS_Q 继续为零,即使我在 Grid 表中将其设置为 6。

我可能做错了,有一种更简单的方法可以做到这一点。我鼓励所有的更正和打击。

【问题讨论】:

    标签: datamapper ruby-datamapper


    【解决方案1】:

    我建议您使用belongs_to 来创建资源之间的关联,并使用身份映射,如下所示:

    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
    

    您在DataMapper.repository(:default) do 发起的区块中所做的一切都将使用身份映射。因此,数据库中相同的对象将导致内存中的相同对象。

    【讨论】:

    • 当你使用belongs_to时,它不需要在它链接到的表上有一个后续的吗?另外,建立这种关联有什么好处。我看不到 DataMapper.repository 块将如何使用这种关系。
    • 只有在需要时才将has n 添加到另一个表中。建立关联的好处是您将真实关联(实际存在)映射到 DM 关联,​​从而充分利用 DM。该块用于确保数据库中的相同对象对应于内存中的相同对象——这意味着当您更改Grid 对象中的AUS_Q 时,与之关联的Driver 对象将看到更改。
    • 这是一个很好的答案。对不起,我花了这么长时间才回来!
    猜你喜欢
    • 1970-01-01
    • 2016-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-04
    相关资源
    最近更新 更多