DataMapper - 为关系数据库创建新值

时间:2011-02-21 16:43:10

标签: heroku sinatra datamapper

我的关系数据库定义如下。如何输入一个新值,其中B属于A.下面给出的代码似乎不起作用。

由于

class A
   include DataMapper::Resource

   property :id, Serial, :key => true
   property :name, String

   belongs_to :b
end

class B
   include DataMapper::Resource

   property :id, Serial, :key => true
   property :name, String

   has n, :as
end

创建新值

 # Create new value
 post '/create' do
   a = A.new

   b = B.new
   b.attributes = params
   b.belongs_to = a #problem is here
   b.save

   redirect("/info/#{a.id}")
 end

2 个答案:

答案 0 :(得分:3)

#belongs_to是一个模型(类)方法,您可以使用它来声明ManyToOne关系。

在您的示例中,您应该使用“<<”像这样的方法:

b.as << a

这会将“a”实例添加到“as”集合并关联两个资源。

答案 1 :(得分:3)

  

[...]如何输入一个新值,其中B属于A.下面给出的代码似乎不起作用。

你的代码暗示你是在属于B的A之后,但你的问题是相反的,所以我将展示如何做到这一点,即B属于A。

class A
   include DataMapper::Resource

   property :id, Serial, :key => true
   property :name, String

   has n, :bs # A has many B's
end

class B
   include DataMapper::Resource

   property :id, Serial, :key => true
   property :name, String

   belongs_to :a, :required => false # B has only 1 A
end

注意你的has和belongs_to在这里是相反的。我还添加了required =&gt;对belongs_to方面是false,因为如果在调用save之前没有b.a,DataMapper将默默地拒绝保存模型 - 一旦你对它感到满意,你可以根据需要删除所需的false。

以下是使用该模型的两种方法:

# Create new value
 post '/create' do
   a = A.new
   a.save

   b = B.new
   b.attributes = params
   b.a = a
   b.save

   redirect("/info/#{a.id}")
 end

这个例子通常和你的一样,但我为A添加了一个保存调用。注意这可能没有必要,我不是一个测试这个特殊情况的好地方;在过去,我发现DataMapper会自动保存一些相关的对象而不是其他对象,所以我养成了一直习惯性地保存,以防止混淆。

 # Create new value
  post '/create' do
    a = A.create
    b = a.bs.create(params)

    redirect("/info/#{a.id}")
  end

在第二个例子中,我在关系的多方面调用create,这使得一个新的B,将它与“a”相关联,设置给定的参数,并立即保存它。结果与前一个示例相同。

如果您只是熟悉DataMapper,您可能会发现将以下内容添加到您的应用中会很有帮助:

DataMapper::Model.raise_on_save_failure = true

这将导致DataMapper在上述情况more info here中为您提供错误和回溯。