我的关系数据库定义如下。如何输入一个新值,其中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
答案 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中为您提供错误和回溯。