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
I think you have your Category associations backwards. belongs_to goes in the model with the foreign key.> 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 > endA Category would have many posts, not belong to only one. Try this: class Post < ActiveRecord::Base belongs_to :author belongs_to :category end class Category < ActiveRecord::Base has_many :posts end --josh -- Posted via http://www.ruby-forum.com/.
Brian V. Hughes
2006-Feb-17 19:47 UTC
[Rails] Re: Using :include with has_one vs. has_many
Joshua Susser wrote:> I think you have your Category associations backwards. belongs_to goes > in the model with the foreign key. > >> 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 > > A Category would have many posts, not belong to only one. Try this: > > class Post < ActiveRecord::Base > belongs_to :author > belongs_to :category > end > > class Category < ActiveRecord::Base > has_many :posts > endNope... I typed exactly what I meant. But, remember, my example was deliberately contrived to show what I''m seeing. Yes, a category could have multiple posts, but in this case they don''t. Also, I''m not looking for help in making "proper" associations (I''m already pretty good at data normalization ;). I''m trying to understand a behavior I''m seeing with has_one associations being used with :include vs. the behavior of has_many associations. -Brian
Yep, as far as I can see through the code, if there is no corresponding record in the database for a has_one association Rails leaves this association uninitialized. Meaning that the first time you try to access it, it''ll try to load it again. Submit the request for improvement. Kent On 2/17/06, Brian V. Hughes <brianvh@alum.dartmouth.org> wrote:> Joshua Susser wrote: > > I think you have your Category associations backwards. belongs_to goes > > in the model with the foreign key. > > > >> 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 > > > > A Category would have many posts, not belong to only one. Try this: > > > > class Post < ActiveRecord::Base > > belongs_to :author > > belongs_to :category > > end > > > > class Category < ActiveRecord::Base > > has_many :posts > > end > > Nope... I typed exactly what I meant. But, remember, my example was deliberately > contrived to show what I''m seeing. Yes, a category could have multiple posts, > but in this case they don''t. > > Also, I''m not looking for help in making "proper" associations (I''m already > pretty good at data normalization ;). I''m trying to understand a behavior I''m > seeing with has_one associations being used with :include vs. the behavior of > has_many associations. > > -Brian > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails >-- Kent --- http://www.datanoise.com