[Nitro] The has_one/belongs_to relationship

Matthew B Gardner weather at speakeasy.net
Mon Aug 20 08:59:40 EDT 2007


Hello -

>On Monday 20 August 2007 06:52, Jonathan Buch wrote:
> Hi,
>
> > Well, my issue is that I need my Account object to reference my Character
> > object and my Character object to refer back to that same Account object.
> > I assumed that the relationship would work like this:
> >load Account
> > load Account#character_oid
> > Account <-> Character
> >But, it's doing this, I think:
> > load Account
> > load Account#character
> > load Character#account
> > Account -> Character -> Account (different instance)
> >
> >>> a1 = Account.new
> >>> a1.character = Character.create self
> >>> a1.equal?(a1.character.account) #=> false
>
> This sums it up I guess, you call a1.character.account so it is
> "Account[25] -> Character[17] -> Account[25]".  Where the first and last
> are the 'same' object, but not identical.
>
> The identify of objects is (imo) mostly irrelevant and hard to 'get to'
> anyway.  When Og wanted to keep the identity for identical (meaning same
> primary key) elements, it'd really have to jump through hoops.  It has
> several other problems then too, like having to keep track of every single
> loaded element (this 'cache' has to be cleaned, when?), making Og
> non-thread- safe (you always work on the identical copy, if you change it
> in one thread it gets changed for all), and the implementation would just
> be so complex and would make Og even slower.
>
> Og theoretically would be able to save the Account in the Character right
> after saving (which I asked George about) which would then point to the
> identical object as the Account.
>
> > Is this how it works then, or did I perhaps implement something
> > incorrectly? Since it's just a one_on_one relationship, I can always
> > reference the Account myself in the Character class, but I was trying to
> > be Ogish and have it load and attach itself. However, it's essential that
> > the created objects reference eachother -- do I need to do the loading
> > myself then
> > (Character.find_by_account_oid(Account#oid), where Character#account_oid
> > is a field created and set by me)?
>
> Well, why would you want to do that by yourself, if Og does it already? 
> When you load it yourself, the object_id you will get will differ in the
> exact same way.
>
> But, to answer your question:  yes, that's how it works.
>
> a1 = Account.create
> c1 = Character.create
> a1.character = c1
> a1.save
> c1.blah # do other stuff
>
> I do this, so if I need the same character in the same scope again, I just
> make it to a local variable, that is imo nicer to read, makes shorter code
> and even is more efficient.
>
> > However, it's essential that the created objects reference eachother
>
> They do, just not to the object with the same object_id, is that really
> a problem?
>

Well, my project is a text-based game in Ruby (a MUD, if you're familiar) -- 
each connection has a <-> reference to an Account object. So, I need the 
Character object to reference the same Account instance that references it -- 
what's happening is that user input is being sent to the Character 
(connection->account->character), but output from the Character is being sent 
to an account with a non-existent connection (character->account->nil). I 
just got rid of the relationship and now keep track of the Account a 
Character belongs to using the method I wrote above, which seems to work 
fine.

> >> Og overrides ==() to react on the primary key of that model.
> >
> >Oh, this probably explains some unexpected results from Array#delete(self)
> > in my Character class -- I assumed it was Og-related, but good to know
> > for sure and why.
>
> Glad it cleared some things up.  :)
>
> Jo

Thanks so much for the help -- I do have one more question, when you get the 
time. I have a Node class that has_many comments (which belong_to a Node) -- 
when I load the Node table, it loads the nodes and loads and attaches the 
comments (which I still find really cool, btw) -- that's all that's happening 
there, correct? What I mean is, the comments aren't also loading their 
respective Nodes, as the Character was loading its Account, are they? Just 
wanted to double check that I don't have a bunch of extra Node instances 
running around.

Thanks again -- I really appreciate all the help you and George have offered.
-Matt


More information about the Nitro-general mailing list