Marcel Hild
2008-Nov-19 18:08 UTC
Overwriting / Decorating ActiveRecord association accessor
Hi, I am trying to overwrite the accessor of a has_many association. Basically my class looks like this: class Person has_many :emails has_one :link, :class_name => ''PersonProxy'' def emails_with_link link.emails + emails_without_link end alias_method_chain :emails, :link end Now that works fine if I only access the collection like>> Person.find(1).emails=> [#<Email...] But using any collection specific methods throw a NoMethodError>> Person.find(1).emails.build=> NoMethodError: undefined method `build'' for #<Array:0x226c634> which makes sense, as I return an array... But how do I return the Association? Or are there any other tricks to implement this decorator for associations? Cheers Marcel --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Frederick Cheung
2008-Nov-19 19:20 UTC
Re: Overwriting / Decorating ActiveRecord association accessor
On Nov 19, 6:08 pm, Marcel Hild <h...-GOUVJj1Of1VeoWH0uzbU5w@public.gmane.org> wrote:> Hi, > I am trying to overwrite the accessor of a has_many association. > Basically my class looks like this: > > class Person > has_many :emails > has_one :link, :class_name => ''PersonProxy'' > > def emails_with_link > link.emails + emails_without_link > end > alias_method_chain :emails, :link > end > > Now that works fine if I only access the collection like>> Person.find(1).emails > > => [#<Email...] > > But using any collection specific methods throw a NoMethodError>> Person.find(1).emails.build > > => NoMethodError: undefined method `build'' for #<Array:0x226c634> > > which makes sense, as I return an array... >The trick is that link.emails isn''t an array - it''s an association proxy. I''m not sure what the write thing to do here is. Maybe something like has_many :emails do def load_target super proxy_target += proxy_owner.link.emails end end might do the trick ? Fred> But how do I return the Association? Or are there any other tricks to > implement this decorator for associations? > > Cheers > Marcel--~--~---------~--~----~------------~-------~--~----~ 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@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Marcel Hild
2008-Nov-20 12:22 UTC
Re: Overwriting / Decorating ActiveRecord association accessor
> > The trick is that link.emails isn''t an array - it''s an association > proxy. > I''m not sure what the write thing to do here is. Maybe something like >Thanks so much for your input. You got me in the right direction: has_many :emails do def load_target super if !loaded? and proxy_owner.link.respond_to?(:emails) @target += proxy_owner.link.emails end @target end end This works like a charm :) Thumbs up! Marcel --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Marcel Hild
2008-Nov-20 12:38 UTC
Re: Overwriting / Decorating ActiveRecord association accessor
I was a bit too fast and euphoric :) Now this works better: has_many :emails do def load_target super if not @loaded_link and proxy_owner.link.respond_to?(:emails) puts "loading link" @target += proxy_owner.link.emails @loaded_link = true end @target end def reset super @loaded_link = false end end --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---