1

So I have a HABTM for both Posts and Topics. A Post HABTM Topics, and a Topic HABTM Posts. What I need to do is call some method in conjunction with calling post.topics=()

This is what I've tried doing in Post.rb:

def topics_with_extra_stuff=(topics)
  topics_without_extra_stuff=(topics)
  extra_stuff()
end
alias_method_chain :topics=, :extra_stuff

However, this now breaks post.topics=()

I won't get an error or anything, but topics() will still be the old value after changing it with topics=()

If I raise an error in topics_with_extra_stuff=, the trace will say that there was an error in topics=, so I know it's getting in there. I also know that extra_stuff() was called.

Here's an example of the output:

>> p = Post.last
=> #<Post id:1 ....>
>> p.topics
=> [#<Topic id:1 ....>, #<Topic id:2 ....>]
>> p.topics = [ p.topics.first ]
=> [#<Topic id:1 ....>]
>> p.topics
=> [#<Topic id:1 ....>, #<Topic id:2 ....>]

It shouldn't still have 2 Topics, just 1.

Thanks for any insight.

solidcell
  • 7,639
  • 4
  • 40
  • 59

2 Answers2

2

I had this same problem (Rails 2.3.11), but adding a before_add callback was not an option for me so I kept looking. Finally I managed to make it work using this alternative way of aliasing:

old_workflows_setter = self.instance_method(:workflows=)

define_method :workflows= do |value|
  # my code
  old_workflows_setter.bind(self).call(value)
end
tokland
  • 66,169
  • 13
  • 144
  • 170
  • 2
    As of rails 3.2 i don't think you'll need to do that - association accessors are created in a module include into your class so you should be able to just redefine and call super() – Frederick Cheung Jul 12 '12 at 15:15
1

I ended up just using the association callback :before_add instead.

solidcell
  • 7,639
  • 4
  • 40
  • 59