Good notes posted by yonosoytu
RSS feed
Needs requiring 'enumerator' to work
This method needs that you
require 'enumerator'
for this method to be available.

Regexes with groups and split
When you use a Regex with capture groups, all capture groups are included in the results (interleaved with the “real” results) but they do not count for the limit argument.
Examples:
"abc.,cde.,efg.,ghi".split(/.(,)/) => ["abc", ",", "cde", ",", "efg", ",", "ghi"] "abc.,cde.,efg.,ghi".split(/(.)(,)/) => ["abc", ".", ",", "cde", ".", ",", "efg", ".", ",", "ghi"] "abc.,cde.,efg.,ghi".split(/(.(,))/) => ["abc", ".,", ",", "cde", ".,", ",", "efg", ".,", ",", "ghi"] "abc.,cde.,efg.,ghi".split(/(.(,))/, 2) => ["abc", ".,", ",", "cde.,efg.,ghi"] "abc.,cde.,efg.,ghi".split(/(.(,))/, 3) => ["abc", ".,", ",", "cde", ".,", ",", "efg.,ghi"]

Using sweepers in script/runner
If you need to use some of your sweepers in a script/runner script or some rake task you can use this snipped:
require 'action_controller/test_process' sweepers = [ProductSweeper, UserSweeper] ActiveRecord::Base.observers = sweepers ActiveRecord::Base.instantiate_observers controller = ActionController::Base.new controller.request = ActionController::TestRequest.new controller.instance_eval do @url = ActionController::UrlRewriter.new(request, {}) end sweepers.each do |sweeper| sweeper.instance.controller = controller end
Your script will fire the ActiveRecord callbacks defined in that sweepers and you can use expire_cache, expire_fragment and also the routing helpers you have defined (hash_for_user_path, hash_for_product_path, etc.).

Explanation about :dependent option
It may seem that :dependent option is only used when the object that has the collection is destroyed, but it is also used every time a associated object is deleted, so if you use
object.collection.delete(associated_object)
your object will be deleted, destroyed or nullified, depending on the value of :dependent option.
With has_many :through associations this option is ignored at least in versions up to 2.1.0, so even if you set :dependent option to :destroy, your join objects will be deleted, not firing any callbacks you have set on destroy events.
If you need to act when your join model is deleted you can use a sweeper or an observer and the association callbacks like this:
# product.rb class Product has_many :categorizations has_many :categories, :through => :categorizations, :before_remove => :fire_before_remove_in_categorizations private def fire_before_remove_in_categorizations(category) categorization = self.categorizations.find_by_category_id(category.id) categorization.class.changed categorization.class.notify_observers(:before_remove, categorization) end end # categorization_sweeper.rb # do not forget to load this sweeper during initialization class CategorizationSweeper < ActionController::Caching::Sweeper observe Categorization def before_remove(categorization) # expire_cache, expire_fragment, whatever end end
One thing you should be aware of it is that you are using before_remove, so you have to be careful because your record may be not be removed (another callback raising an exception or the database not deleting the record) so you can not be sure your object will be delete. Expiring caches is safe because even if your record is not destroyed your cache will be regerated correctly.
You can not use after_remove, because at that point the join model do not exists anymore, so you can not fire its callbacks. But you have the model id and the associated model id, so if you do not need expiring caches maybe you can use this approach (expiring caches can be only done in a sweeper or in a controller, but with after_remove you are bound to your model).