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
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
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
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