has_many with set target

Why has_many doesn't set target for objects in its collection?

E.g. when

  class Author < ActiveRecord; has_many :posts; end   class Post < ActiveRecord; belongs_to :author; end

then

  some_author.posts.each {|p| puts p.author.name}

will require additional queries to fetch author for each post.

Could some option to has_many be added to pre-fill the target (in this case set_author_target for each post)?

Something like:

module ActiveRecord   module Associations # :nodoc:     module ClassMethods

      # When called with <tt>:fill_target => name</tt> it will fill targets in each object in association       # E.g.: when Author <tt>has_many :posts, :fill_target => "author"</tt>       # then <tt>some_author.posts.each {|m| m.author.name }</tt> will not require aditional db queries to fetch author for each post       # (it will use the +some_author+ already from memory)

Wait a min..

some_author.posts.each {|p| puts p.author.name}

p.author.name == some_author.name !

This mailing list is meant for discussion about implementation details of Rails only. You can post support requests to Rails Talk [1] or #rubyonrails on freenode.

[1] http://groups.google.com/group/rubyonrails-talk

Sorry, but I thought it is about Rails implementation details, has_many implementation details.

This mailing list is meant for discussion about implementation
details of Rails only. You can post support requests to Rails Talk
[1] or #rubyonrails on freenode.

[1]http://groups.google.com/group/rubyonrails-talk

> Why has_many doesn't set target for objects in its collection?

> E.g. when

> class Author < ActiveRecord; has_many :posts; end > class Post < ActiveRecord; belongs_to :author; end

> then

> some_author.posts.each {|p| puts p.author.name}

> will require additional queries to fetch author for each post.

That said, some_author.posts.find(:all, :include => :author).each { | p> puts p.author.name } will do a JOIN for you. Although that
shouldn't be necessary if you put some_author in an instance variable
and read it from there.

Manfred

That said, :include is not a solution, cause it also unnecessarily makes bigger query just to fetch object which I already have in memory. Instant variable is not enough. My example was intentionally simple just to show what I mean. Imagine that I have few authors somewhere, and I collect their posts, and this posts list is accessed from outside. Also I was more hoping to see opinion about suggested extension to has_many.

paccator

That said, :include is not a solution, cause it also unnecessarily makes bigger query just to fetch object which I already have in memory. Instant variable is not enough. My example was intentionally simple just to show what I mean. Imagine that I have few authors somewhere, and I collect their posts, and this posts list is accessed from outside. Also I was more hoping to see opinion about suggested extension to has_many.

ActiveRecord on edge rails has a cache that is active in ActionController requests so this shouldn't be a problem. I also have a plugin that takes a slightly different route in caching frequently accessed records in a single request.

http://activereload.net/2007/5/23/spend-less-time-in-the-database-and-more-time-outdoors

It's definitely possible to do some form of bidirectional association at present. You just need to either calculate or configure the belongs_to association which is the inverse of the has_many.

For some simple cases calculation could work. However it starts to get quite tricky when the has_many has :conditions or :includes applied, or if there are multiple has_many associations etc.

However if you whip up a plugin or patch which implements this, I'm sure there are people who'd help out with testing it. It's a surprising gotcha for some users.

Having said that, rick's context plugin implements an identity map, so it could be worth investigating first.

Sorry, I think I misunderstood you're problem.

Manfred