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