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
Are you using the acts_as_tree plugin? -- http://github.com/rails/acts_as_tree/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