Reputation: 23
I have a relational DB defined as follows. How can I enter a new value, where B belongs to A. The code given below doesn't seem to work.
Thanks
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
# 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
Upvotes: 0
Views: 251
Reputation: 1813
[...] How can I enter a new value, where B belongs to A. The code given below doesn't seem to work.
Your code implies you're after A belonging to B, but your question is the reverse so I'll show how to do that, i.e., B belongs to 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
Note your has and belongs_to are reversed here. I also added required => false to the belongs_to side because DataMapper will silently refuse to save your model if ever don't have b.a before calling save—once you're comfortable with it you can remove the required false if you desire.
Here are two ways you can use that model:
# 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
This example is generally the same as yours, but I added a save call for A. Note this may not be necessary, I'm not in a good place to test this particular case; in the past I've found DataMapper will save some related objects automatically but not others so I've developed the habit of always saving explicitly to prevent confusion.
# Create new value
post '/create' do
a = A.create
b = a.bs.create(params)
redirect("/info/#{a.id}")
end
In the second example I call create on the many-side of the relationship, this makes a new B, associates it with "a", sets the params given, and saves it immediately. The result is the same as the previous example.
If you're just getting familiar with DataMapper, you may find it helpful to add the following to your app:
DataMapper::Model.raise_on_save_failure = true
This will cause DataMapper to give you errors and backtraces in cases like the above, more info here.
Upvotes: 3
Reputation: 5743
#belongs_to is a model (class) method and you use it to declare ManyToOne relationship.
In your example you should use "<<" method like this:
b.as << a
That will add "a" instance to "as" collection and associate both resources.
Upvotes: 3