0

Can't figure out why this would be happening:

class Foo < ActiveRecord::Base
  belongs_to :belongable, :polymorphic => true

  def after_save 
    if belongable.kind_of?(User)
      send(:some_method)
    end
  end
end

class Bar < Foo

  def some_method
    #Do something
  end
end

class Group < ActiveRecord::Base
  has_many :belongings, :as => :belongable
end

class User < ActiveRecord::Base
  has_many :belongings, :as => :belongable
end

The class 'Bar' is an STI model that inherits from Foo (Foo has a 'type' attr). Both Groups and Users are able to have many Bars.

The following works as expected (some_method doesn't get called):

g = Group.create
g.belongings << Bar.new
g.save

The following calls some_method:

Group.first.belongings.first.update_attributes(:attr => :val)

How/Why?! Why isn't the condition in the 'after_save' callback being evaluated once the association already exists?

user1032752
  • 751
  • 1
  • 11
  • 28

3 Answers3

0

Group.create.belongings << Bar.new never saves Bar to the database. So after_save is never called. The second example uses update_attributes which does save to the database. That is why it triggers after_save.

Logan Serman
  • 29,447
  • 27
  • 102
  • 141
  • Thank you for your reply. But why does the condition in the callback evaluate to true and therefore call 'some_method' when the class of the parent is Group not User? – user1032752 Mar 31 '13 at 17:42
0

This is a mix of STI and Polymorphism. Your Foo model should have belongable_type and belongable_id attributes.

I am not exactly able to shoot it down, but changing your comparison to this should work :

belongable_type == "User"
Nerve
  • 6,463
  • 4
  • 29
  • 29
0

"some_method" can't be called "update"... :-/

AR objects already define a method called update (http://apidock.com/rails/ActiveRecord/Persistence/update) and this method get's called when you call 'update_attributes'.

user1032752
  • 751
  • 1
  • 11
  • 28