While I’m happy to continue talking about the vagaries of Rails
deployments, I
also need to actually build apps.
I may have discovered a bit of a problem with :include as it applies to
has_one
associations. First, let me say that I’m a big fan of :include for
reducing the
number of SQL calls. There are times when I wish it could go more than 1
step
away from the parent object, but I kind of understand why it can’t. Now,
on to
my “discovery”…
Completely contrived example follows:
I have the following Models:
class Author < ActiveRecord::Base
has_many :posts
end
class Post < ActiveRecord::Base
belongs_to :author
has_one :category
end
class Category < ActiveRecord::Base
belongs_to :post
end
There are many authors in the database that no posts, and there are
several
posts in the database that have no category.
If I do:
@authors = Author.find(:all, :include => :posts)
Every entry in the @authors array will have a posts list attached to it.
This
list will be empty if there are no posts for that author, which is great
for
handling associated posts in a view.
However, if I do:
@posts = Post.find(:all, :include => :category)
We actually see something different (and I think, inconsistent). Only
those post
objects that have an associated category will have a category entry in
their
hash. Those without, don’t have a category entry.
Sorry for the length… here’s my actual question.
Why doesn’t :include result in an empty object in those posts without an
associated category record? If I loop over @posts and make a call to:
post.category.nil?
ActiveRecord ends up making additional SQL calls for every case where
that
statement evals to true. Why doesn’t the :include “work” for these
cases?
OK, so I really had 2 questions…
-Brian