Using PostgreSQL
and DataMapper
to build a Sinatra app, running into some problems with DataMapper
(I'm very new to it, used to Rails/AR
). For every Account
created, it can either be an Artist
, Venue
, or Fan
. Only one, no combining.
When the user signs up, I can create the Account
instance fine, but I'm having trouble creating the account's has 1 Artist
or Venue
or Fan
instance (for ease of conversation, we'll use Artist
as the belonging model).
Here's my current model declarations:
class Account
include DataMapper::Resource
property :id, Serial
...
has 1, :artist, :required => false
has 1, :venue, :required => false
has 1, :fan, :required => false
end
class Artist
include DataMapper::Resource
# no ID
...
belongs_to :account, :key => true
end
class Venue
include DataMapper::Resource
# no ID
...
belongs_to :account, :key => true
end
class Fan
include DataMapper::Resource
# no ID
...
belongs_to :account, :key => true
end
And here's how I'm trying to go about the sign up process:
account = Account.create(
...
)
account.Artist = Artist.create(:bio => "test")
This is currently giving me next error:
undefined method `Artist=' for #<Account:0x007ff2af289840>
I guess you should use lowercase letter in referring model:
account.artist = Artist.create(:bio => "test")
This line:
has 1, :artist, :required => false
Add a relation, by which you can refer from Account
to Artist
.
Updated
This answer has exactly your model and seems like it worked. There is DataMapper.finalize
thing, i guess you made it.
After a lot of frustration, I figured this out. i hope my answer helps anyone else out, as I couldn't find anything on the internet that outlined this (maybe I'm just bad at searching).
Per @zishe's updated answer, I followed the structure he linked to, like thus:
class Account
include DataMapper::Resource
property :id, Serial
...
has 1, :artist
has 1, :venue
has 1, :fan
end
class Artist
include DataMapper::Resource
# no ID
...
belongs_to :account, :key => true
end
And for creating associated records:
a = Account.create(...)
a.artist = Artist.create(...)
Creating the parent record, the Account, worked fine, but the belonged record, Artist, was not created nor was an error reported. After some frustration, I stumbled upon dm-noisy-failures, which I 'gem installed' and required in my app. Note to other data_mapper noobs, that gem is a must have, and I personally think it's an extremely awry decision on datamapper's part to hide errors the way it does. Thanks to dm-noisy-failures, my error was made clear to me. The solution was to manually tell data_mapper the ID of the parent record when creating the Artist record, like thus:
a = Account.create(...)
a.artist = Artist.create(:account_id => a.id)
Worked like a charm. Thank you @zishe (point given) and contributors of the linked answer.
UPDATE: so now i really feel like an idiot. tucked away in DataMapper's Associations documentation under the subheader Adding To Associations (contrary to my comment below) is an example that explains exactly how to do 1-to-1 relationships. i completely overlooked this. sorry everyone, ashamed.