Best way to set a self-reference attribute on create?

14 views
Skip to first unread message

George

unread,
Nov 3, 2009, 5:21:41 AM11/3/09
to DataMapper
Imagine a Model named "Trip".
When creating a new trip it's activeTrip attribute must default to
itself.
(So it becomes self-refencing FK in the database table)

The following code does not seem to work. After creating a new object
the active_trip_id field is blank in the database. Any ideas what I'm
doing wrong?

class Trip
include DataMapper::Resource
property :id, Serial
property :name, String, :default => "A lovely new trip"

# Self-referencing FK trip.activeTrip:
has 1, :activeTrip, :class_name => "Trip", :child_key =>
[:active_trip_id]
belongs_to :trip, :class_name => "Trip", :child_key =>
[:active_trip_id]

# Default activeTrip to itself if none specified:
before :save do
activeTrip ||= self
end
end

BIG thanks for your help!
George

Dan Kubb (dkubb)

unread,
Nov 3, 2009, 5:36:58 AM11/3/09
to DataMapper
George,

> The following code does not seem to work. After creating a new object
> the active_trip_id field is blank in the database. Any ideas what I'm
> doing wrong?

...

>     # Default activeTrip to itself if none specified:
>     before :save do
>       activeTrip ||= self
>     end

The first thing I'd try is prefix the assignment with self, eg:
self.activeTrip ||= self

Without that you're assigning to a local variable, not the object
accessor/mutator.

--

Dan
(dkubb)

Martin Gamsjaeger

unread,
Nov 3, 2009, 9:14:15 AM11/3/09
to datam...@googlegroups.com
George,

Here's a link where I tried to collect information on when to use
self. with datamapper (of course, this is all due to how ruby works,
nothing special with datamapper)

http://alfred.datamapper.org/posts/21

cheers
snusnu

George

unread,
Nov 4, 2009, 7:44:11 AM11/4/09
to DataMapper
Thanks for the advice. The "self" thing makes sense.

Interestingly, any attempts to set self.activeTrip caused a recursive
spiral of death ("Stack level too deep")
But I discovered that setting the active_trip_id property was the only
solution that worked safely, (also using "after :create" instead of
"before :save")

after :create do
# Set activeTrip if not already set:
if self.activeTrip.nil?
self.active_trip_id = self.id
self.save
end
end
Reply all
Reply to author
Forward
0 new messages