has_many and habtm callbacks 6

Posted by pratik
on Tuesday, October 16

Very few people are aware of existence of has_many and habtm association callbacks : before/after_add & before/after_remove as they’re hidden somewhere deep inside documentation. But until now they were very much unusable and buggy. Thanks to bitsweat’s commit of my patch, now we can actually use them :-)

This can be a great step towards our famous Skinny Controller, Fat Model methodology, as these callbacks allow you to move a great amount of logic to models :

1
2
3
4
5
6
7
8
9
10
11
class Client < ActiveRecord::Base  
  has_many :employees, :after_add => :assign_project, :after_remove => :reassign_projects
  
  def assign_projects(employee)
    ...
  end
  
  def reassign_projects(employee)
    ...
  end
end

These callbacks still may have some room for improvement, please do use them and report back any issues you face with them at Rails Trac and you can add me ( trac username : lifofifo ) to the CC list of you ticket.

Comments

Leave a response

  1. RSLOctober 16, 2007 @ 01:38 PM

    First!!

  2. RSLOctober 18, 2007 @ 12:29 AM

    Second.

  3. RSLOctober 18, 2007 @ 12:30 AM

    Shall we third? ;)

  4. MarkúsOctober 19, 2007 @ 09:24 AM

    Hi!

    At last!, a reliable assocation callbacks.

    I waste a lot of time fighting with old implementation when the callbacks, once defined, were called only in some circumstances. For example, as far as I know, the before_add callback is only executed when you write model.associations << association and not when you write model.associations.create.

    Before read the changeset and the tests I confirm that the improvements are great, now I can write model.association.create and define callbacks for it.

    Great job!

  5. Eugene HlyzovNovember 16, 2007 @ 08:11 AM

    Thank you! It’s really very useful feature. Will use these callbacks from now :-)

  6. FeurioMay 29, 2008 @ 10:29 PM

    Hi,

    just found out about this great feature. Then I tried to use it on an existing User model I have.

    class User < ActiveRecord::Base has_many :my_interests, :order => nil, :extend => [], :foreign_key => “category_id”, :limit => nil, :offset => nil, :conditions => ‘category_type = “interest”’, :group => nil, :through => :categorized_items, :source => :category, :class_name => “Category”, :after_add => :log_me

    def log_me(category) puts ”\n** it works *\n” end end

    class Category < ActiveRecord::Base has_many_polymorphs :items, :from => [ :users, :resources ], :through => :categorized_items end

    class CategorizedItem < ActiveRecord::Base belongs_to :category, :counter_cache => true belongs_to :item, :polymorphic => true end

    Everythings works as far as the basic association magic is concerned.

    I can add a Category to a user like this:

    user.my_interests << Category.find(1)

    But what is not working is that the :after_add association callback is not triggered.

    Am I doing something wrong? Any ideas how I can corner this issue?

    I use:

    Rails 2.0.2 ruby 1.8.6 (2007-06-07 patchlevel 36) [x86_64-linux

    Help is greatly appreciated!

    Feurio

Comment