[Nitro] The has_one/belongs_to relationship
Matthew B Gardner
weather at speakeasy.net
Mon Aug 20 08:59:40 EDT 2007
>On Monday 20 August 2007 06:52, Jonathan Buch wrote:
> > 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 -> Character -> Account". 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
> 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
> >> 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. :)
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
Thanks again -- I really appreciate all the help you and George have offered.
More information about the Nitro-general