复合主键仅用于访问记录,但不用于保存data_mapper中的记录

时间:2013-01-17 23:45:26

标签: ruby composite-primary-key ruby-datamapper

我有一个应用程序可以跟踪玩家在健身计划上的进度。所以每个玩家都有多周时间相同:week_id

Week_id与belongs_to关系相结合是Week记录的复合主键。

然而,当我尝试使用属于不同玩家的相同week_id创建两周时,我得到一个“列week_id不唯一”错误。

我觉得自己走在正确的轨道上,因为当我想获取一周的记录时,它告诉我需要两个参数来获取它 - week_id和player_id。

我可能在这里遗漏了一些简单的东西。我希望你能告诉我。

require "rubygems"  
require "json"
require "sqlite3"
require "data_mapper"
require "bigdecimal"



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

DataMapper::Model.raise_on_save_failure = true

class Player

    include DataMapper::Resource

    property :name, String, :key => true
    property :age, Integer

    has n, :weeks

end

class Week

    include DataMapper::Resource

    property :week_id, Integer, :key => true
    property :score, Integer

    belongs_to :player, :key => true

end

DataMapper.finalize.auto_migrate!

@jack = Player.create(:name => "jack")
@jack.weeks.create(:week_id => 1)

@jill = Player.create(:name => "jill")
@jill.weeks.create(:week_id => 1)

2 个答案:

答案 0 :(得分:2)

看起来你已经想出了一个解决方案,但我会继续为后代发布另一个答案,因为我遇到了同样的问题。

似乎将':player_name'声明为关键属性以及'belongs_to'声明,您最终会使用相同的SQL来创建表,但它也会识别出week_id是a的一部分复合键,不需要是唯一的。 (似乎DataMapper在“property”和“belongs_to”声明中分割了复合键的问题。)

class Week

    include DataMapper::Resource

    property :week_id, Integer, :key => true
    property :player_name, String, :key => true
    property :score, Integer

    belongs_to :player, :key => true

end

在以下SQL中创建表:

〜(0.000000)CREATE TABLE“周”(“week_id”INTEGER NOT NULL,“player_name”VARCHAR(50)NOT NULL,“score”INTEGER,PRIMARY KEY(“week_id”,“player_name”))

您的示例代码可以正常运行

答案 1 :(得分:1)

所以我最终对我的周模型进行了一些小改动,如此

class Week

    include DataMapper::Resource

    property :id, String, :key => true
    property :week_id, Integer
    property :score, Integer

    belongs_to :player

end

每当我创建一个新的Player模型时,我会连接外键和week_id来创建id字符串

所以我的id字符串看起来像“jack1”,对于一个玩家的第一条记录:id为“jack”

不确定这是否是data_mapper方式,但它可以正常工作。