views:

97

answers:

1

I have a model which uses acts-as-tree. For example:

class CartoonCharacter < ActiveRecord::Base
  acts_as_tree
end

Acts as tree has these associations:

class ActsAsTree
  belongs_to :parent
  has_many :children
end

From script/console I am building my tree, saving nothing until the entire tree is constructed. The trouble I am having is that prior to committing to the database I am unable to successfully navigate the tree. Calls to #parent and #sibling produce questionable results. I can only assume I'm missing something.

fred=CartoonCharacter.new(:name=>'Fred')
fred.children.build(:name => 'BamBam')
pebbles = fred.children.build(:name => 'Pebbles')

fred.children #=> [BamBam, Pebbles]
fred.children.last.parent #=> nil --- why not Fred?
pebbles.siblings #=> [completely unrelated records from db??]

I am guessing this has something to do with the way associations are handled. I would have imagined that in-memory ActiveRecord structures would be completely navigable, but they don't seem to be. From forcing logging to the console I've sometimes noted that navigating across associations causes database access. This makes it difficult to know how to circumnavigate associations. (I looked briefly into query caching.) How are others handling this? Or are you always committing records and their relations as you go? This is puzzling.


EDIT:

What appears to solve this problem is to set both relations at the same time. That is, the missing piece was:

pebbles.parent = fred
bambam.parent = fred

Is this by design? That is, are we always expected to set both parts of a reciprocal relationship?


EDIT:

Related question

A: 

Are you using the acts_as_tree plugin? -- http://github.com/rails/acts%5Fas%5Ftree/tree/master

It will work the way you want/expect.

If you're rolling this data structure by yourself, your associations as described in the OP are not complete--they're referring to different foreign keys.

belongs_to :parent  # parent_id field in this model
has_many :children  # child_id field in the child models

So currently, there are two different associations between pairs of instances. That's why you're having to make two assignment statements.

Instead of the above, something more like

belongs_to :parent, :class_name => "CartoonCharacter", 
  :foreign_key => :tree_key

has_many :children, :class_name => "CartoonCharacter",
  :foreign_key => :tree_key

Larry

Larry K
Thanks for taking the time to get back to me. I couldn't get it to work even though I believe I've set everything up properly. I did get this to work by using the after_add callback on the children and assigning the parent there.
Mario