Active Resource Callbacks

Posted by paul

It looks like work is still on-going to extract functionality common to Active Record and Active Resource into a new Active Model library. Excellent. But I wanted to add a couple of callbacks to Active Resource and I wanted to do it quickly. Thankfully, someone much smarter than me has already extracted callbacks from Active Record, so getting something working was pretty straight forward.

module ActiveResource
  module Callbacks
    CALLBACKS = %w( after_save after_destroy )
    
    def self.included(base)
      [:save, :destroy].each do |method|
        base.send :alias_method_chain, method, :callbacks
      end
      
      base.send :include, ActiveSupport::Callbacks
      base.define_callbacks *CALLBACKS
    end
    
    def save_with_callbacks
      returning save_without_callbacks do
        run_callbacks(:after_save) unless new?
      end
    end
    
    def destroy_with_callbacks
      returning destroy_without_callbacks do
        run_callbacks(:after_destroy)
      end
    end
  end
end

ActiveResource::Base.send :include, ActiveResource::Callbacks

How to Bypass attr_accessible and attr_protected in Rails

Posted by paul

Mass assignment in Rails is super handy and saves heaps of code, especially in your controllers. As everyone knows however, hackers love mass assignment so you really need to use attr_accessible or attr_protected to protect your models.

But what happens if you want to mass assign model attributes which are otherwise protected? It would be simple enough to create your own method to do this, but if you take a look at the source you'll see that Rails already has it covered. Here's the method signature for ActiveRecord::Base#attributes=:

def attributes=(new_attributes, guard_protected_attributes = true)

That optional second parameter lets you bypass attr_accessible and attr_protected exactly as we'd like. But how do we call this? Well, you use send.

@model.send :attributes=, attributes, false