Consider this situation
class Property < ActiveRecord::Base
has_many :photos
end
Now if you reference:
@property.photos[0].property
It reloads the property. I''m looking for a way to suggest the
association directly to the associated objects.
I know this example seems contrived, but it''s just a simplification.
In actuality my Photo model has a method that looks like this:
class Photo < ActiveRecord::Base
def public_filename
File.join("images", property.idx.name, filename)
end
end
Not only does this result in n+1 queries, but it actually results in 2n
+1, even though I am eager loading all the necessary data up front.
I can think of a lot of ways to solve this, but to cleanly solve it
requires somehow suggesting the existing loaded @property object to
the photo.property assocation. If there''s no way to do this, maybe
there should be...
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Talk" group.
To post to this group, send email to
rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en
-~----------~----~----~----~------~----~------~--~---
dasil003 wrote:> Consider this situation > > class Property < ActiveRecord::Base > has_many :photos > end > > Now if you reference: > > @property.photos[0].property > > It reloads the property. I''m looking for a way to suggest the > association directly to the associated objects. > > I know this example seems contrived, but it''s just a simplification. > In actuality my Photo model has a method that looks like this: > > class Photo < ActiveRecord::Base > def public_filename > File.join("images", property.idx.name, filename) > end > end > > Not only does this result in n+1 queries, but it actually results in 2n > +1, even though I am eager loading all the necessary data up front. > > I can think of a lot of ways to solve this, but to cleanly solve it > requires somehow suggesting the existing loaded @property object to > the photo.property assocation. If there''s no way to do this, maybe > there should be...Yes, back associations aren''t currently found and set automatically. You can have it done automatically for your association: class Property < ActiveRecord::Base has_many :photos def photos_with_back_links(*params) photos_without_back_links(*params).each { |p| p.property = self } end alias_method_chain :photos, :back_links end -- We develop, watch us RoR, in numbers too big to ignore. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Very cool solution, looking up alias_method_chain was well worth it.
There is one problem when calling a method on the association proxy
that doesn''t actually return an array of Photos such as:
@property.photos.count
I dug into AssocationProxy and it''s subclasses to figure out how best
to make this work. I think something like:
class Property < ActiveRecord::Base
has_many :photos
def photos_with_back_links(*params)
result = photos_without_back_links(*params)
result.each { |p| p.set_property_target = self } if result.is_a?
(Array)
end
alias_method_chain :photos, :back_links
end
will work generally, although it could still choke on methods that
return an array that''s not a list of photos... is it worth putting a
conditional inside the loop?
On Jun 11, 10:22 pm, Mark Reginald James
<m...-bzGI/hKkdgQnC9Muvcwxkw@public.gmane.org>
wrote:> dasil003 wrote:
> > Consider this situation
>
> > class Property < ActiveRecord::Base
> > has_many :photos
> > end
>
> > Now if you reference:
>
> > @property.photos[0].property
>
> > It reloads the property. I''m looking for a way to suggest
the
> > association directly to the associated objects.
>
> > I know this example seems contrived, but it''s just a
simplification.
> > In actuality my Photo model has a method that looks like this:
>
> > class Photo < ActiveRecord::Base
> > def public_filename
> > File.join("images", property.idx.name, filename)
> > end
> > end
>
> > Not only does this result in n+1 queries, but it actually results in
2n
> > +1, even though I am eager loading all the necessary data up front.
>
> > I can think of a lot of ways to solve this, but to cleanly solve it
> > requires somehow suggesting the existing loaded @property object to
> > the photo.property assocation. If there''s no way to do this,
maybe
> > there should be...
>
> Yes, back associations aren''t currently found and set
automatically.
> You can have it done automatically for your association:
>
> class Property < ActiveRecord::Base
> has_many :photos
> def photos_with_back_links(*params)
> photos_without_back_links(*params).each { |p| p.property = self }
> end
> alias_method_chain :photos, :back_links
> end
>
> --
> We develop, watch us RoR, in numbers too big to ignore.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Talk" group.
To post to this group, send email to
rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en
-~----------~----~----~----~------~----~------~--~---
Actually the other methods don''t work at all. This technique can''t really solve the problem satisfactorily because the array isn''t loaded until a method is called on the proxy that needs it. This alias- chaining is too early. The method to chain is find_target in AssociationCollection, but that is considerably trickier to pull off... On Jun 13, 4:57 pm, dasil003 <gabrie...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Very cool solution, looking up alias_method_chain was well worth it. > > There is one problem when calling a method on the association proxy > that doesn''t actually return an array of Photos such as: > > @property.photos.count > > I dug into AssocationProxy and it''s subclasses to figure out how best > to make this work. I think something like: > > class Property < ActiveRecord::Base > has_many :photos > def photos_with_back_links(*params) > result = photos_without_back_links(*params) > result.each { |p| p.set_property_target = self } if result.is_a? > (Array) > end > alias_method_chain :photos, :back_links > end > > will work generally, although it could still choke on methods that > return an array that''s not a list of photos... is it worth putting a > conditional inside the loop? > > On Jun 11, 10:22 pm, Mark Reginald James <m...-bzGI/hKkdgQnC9Muvcwxkw@public.gmane.org> wrote: > > > dasil003 wrote: > > > Consider this situation > > > > class Property < ActiveRecord::Base > > > has_many :photos > > > end > > > > Now if you reference: > > > > @property.photos[0].property > > > > It reloads the property. I''m looking for a way to suggest the > > > association directly to the associated objects. > > > > I know this example seems contrived, but it''s just a simplification. > > > In actuality my Photo model has a method that looks like this: > > > > class Photo < ActiveRecord::Base > > > def public_filename > > > File.join("images", property.idx.name, filename) > > > end > > > end > > > > Not only does this result in n+1 queries, but it actually results in 2n > > > +1, even though I am eager loading all the necessary data up front. > > > > I can think of a lot of ways to solve this, but to cleanly solve it > > > requires somehow suggesting the existing loaded @property object to > > > the photo.property assocation. If there''s no way to do this, maybe > > > there should be... > > > Yes, back associations aren''t currently found and set automatically. > > You can have it done automatically for your association: > > > class Property < ActiveRecord::Base > > has_many :photos > > def photos_with_back_links(*params) > > photos_without_back_links(*params).each { |p| p.property = self } > > end > > alias_method_chain :photos, :back_links > > end > > > -- > > We develop, watch us RoR, in numbers too big to ignore.--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
class Property < ActiveRecord::Base
has_many :photos do
def hydrate
each {|x| x.set_property_target @owner}
end
end
end
Property.find(:all, :limit => 10, :include => :photos).each {|x|
x.photos.hydrate}
Trevor
On 6/13/07, dasil003 <gabriel.d-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
wrote:>
> Actually the other methods don''t work at all. This technique
can''t
> really solve the problem satisfactorily because the array isn''t
loaded
> until a method is called on the proxy that needs it. This alias-
> chaining is too early.
>
> The method to chain is find_target in AssociationCollection, but that
> is considerably trickier to pull off...
>
> On Jun 13, 4:57 pm, dasil003
<gabrie...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> > Very cool solution, looking up alias_method_chain was well worth it.
> >
> > There is one problem when calling a method on the association proxy
> > that doesn''t actually return an array of Photos such as:
> >
> > @property.photos.count
> >
> > I dug into AssocationProxy and it''s subclasses to figure out
how best
> > to make this work. I think something like:
> >
> > class Property < ActiveRecord::Base
> > has_many :photos
> > def photos_with_back_links(*params)
> > result = photos_without_back_links(*params)
> > result.each { |p| p.set_property_target = self } if result.is_a?
> > (Array)
> > end
> > alias_method_chain :photos, :back_links
> > end
> >
> > will work generally, although it could still choke on methods that
> > return an array that''s not a list of photos... is it worth
putting a
> > conditional inside the loop?
> >
> > On Jun 11, 10:22 pm, Mark Reginald James
<m...-bzGI/hKkdgQnC9Muvcwxkw@public.gmane.org> wrote:
> >
> > > dasil003 wrote:
> > > > Consider this situation
> >
> > > > class Property < ActiveRecord::Base
> > > > has_many :photos
> > > > end
> >
> > > > Now if you reference:
> >
> > > > @property.photos[0].property
> >
> > > > It reloads the property. I''m looking for a way to
suggest the
> > > > association directly to the associated objects.
> >
> > > > I know this example seems contrived, but it''s just
a simplification.
> > > > In actuality my Photo model has a method that looks like
this:
> >
> > > > class Photo < ActiveRecord::Base
> > > > def public_filename
> > > > File.join("images", property.idx.name,
filename)
> > > > end
> > > > end
> >
> > > > Not only does this result in n+1 queries, but it actually
results in 2n
> > > > +1, even though I am eager loading all the necessary data up
front.
> >
> > > > I can think of a lot of ways to solve this, but to cleanly
solve it
> > > > requires somehow suggesting the existing loaded @property
object to
> > > > the photo.property assocation. If there''s no way
to do this, maybe
> > > > there should be...
> >
> > > Yes, back associations aren''t currently found and set
automatically.
> > > You can have it done automatically for your association:
> >
> > > class Property < ActiveRecord::Base
> > > has_many :photos
> > > def photos_with_back_links(*params)
> > > photos_without_back_links(*params).each { |p| p.property =
self }
> > > end
> > > alias_method_chain :photos, :back_links
> > > end
> >
> > > --
> > > We develop, watch us RoR, in numbers too big to ignore.
>
>
> >
>
--
--
Trevor Squires
http://somethinglearned.com
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Talk" group.
To post to this group, send email to
rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en
-~----------~----~----~----~------~----~------~--~---
dasil003 wrote:> Actually the other methods don''t work at all. This technique can''t > really solve the problem satisfactorily because the array isn''t loaded > until a method is called on the proxy that needs it. This alias- > chaining is too early.Yes, I''d only considered the case where the unadorned whole collection was being fetched, not the use of proxy methods. I now have a better understanding of the delayed loading the proxy implements by defining the respond_to? method. The "each" triggers the load of the whole association, so rather than aliasing the association name you''d have to have a separate method for the back-linked version, only used when you want the whole collection. -- We develop, watch us RoR, in numbers too big to ignore. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---