Glad You're Ready. Let's Get Started!

Let us know how we can contact you.

Thank you!

We'll respond shortly.

Advanced Proxy Usage, Part I

One of the more underutilized features of ActiveRecord is the Assocation Proxy. But they are also one of the most powerful weapons in the ActiveRecord armory, and Rails apps that take advantage of them are better organized and easier to maintain.

What is a Proxy?

When in an ActiveRecord you declare an Association:

class Hand < ActiveRecord::Base
  has_many :fingers

Instances of Hand now have a fingers method. Contrary to appearances, and contrary to the LIE told to you by hand.fingers.class, the fingers method does not return an Array of Fingers. Rather it returns a Proxy object, one that smells and tastes like an Array of fingers but actually has a rich creamy behavior all its own.

Scoped Access

The most basic use of Proxies is to “scope” the reading and writing of your ActiveRecords. For example, if you have a controller that allows CRUD on a User’s Assets, you can read and write to the collection of Assets as in the following examples:

@asset = current_user.assets.find(params[:id])
@asset = current_user.assets.create(params[:asset])
@asset =[:asset]) # equivalent to 'new'-ing an object rather than 'create'-ing it.

There are other ways of doing this, of course:

@asset = Asset.create({:user => current_user}.merge(params[:asset))

But the Proxy Code is much better: not only is the Proxy code terse, but it meaningfully expresses the relationship between objects in your domain: Users have many assets; this Asset is created in the context of this User.

Special Queries (or Custom Finders)

The various Association declarations–has_many, belongs_to, etc.–allow you to express much more than a simple Foreign Key relation. We can richly express in the Proxy Declarations concepts like ‘Assets that belong to a User’ and ‘Assets that don’t belong to a User':


simply by declaring:

class User
  has_many :my_assets, :class_name => 'Asset', :conditions => 'user_id = #{id}'
  has_many :other_assets, :class_name => 'Asset', :conditions => 'user_id != #{id}'

Notice, in this last example, something peculiar: the use of single quotes (”) with variable substitution (#{…}). This is not a typo: the use of double-quotes, would perform variable interpolation when the has_many declaration is invoked. This is in the class-context–i.e., there is no instance yet. Rails always calls eval with a Binding of self when a call to one of the Proxy methods is performed, ensuring that this all comes together.

Let’s consider an alternative to this approach: declaring finders as instance methods.

class User
  def other_assets
    assets.find(:conditions => ["user_id != ?", id])

What’s wrong with this approach? Well, if you want to use this query in anything non-trivial–such as selecting the first ten of a User’s Assets–you have to write fancy code:

def other_assets(options)
  assets.find({:conditions => ...}.merge(options))

But good luck using this strategy to do pagination. You need to define my_assets and my_assets_count, too–have fun keeping your code DRY. With a proxy, we can just do something like:


In fact, all the richness of ActiveRecord class methods (and any other class methods of the Target type) are available to you here. Want to find all of a User’s assets that are in State pending?


Another example:

class Asset
  def self.find_portrait_assets
    find(:all, :conditions => 'height > width')



returns only those portrait assets owned by a user.

Proxy Options

Proxy declarations accept a number of interesting parameters. There are even “lifecycle” callbacks, like after_add, and before_destroy just like a normal ActiveRecord has before_create and so forth. You can hook into these by using an option.

class User
  has_many :assets, :after_add => [:send_email] do
  def send_email(r)

This after_add could be defined in the Asset class. But suppose Assets had a Polymorphic association. Both Users and Articles have many Assets. Our Business Rule is only to send email when a User adds an Asset, not an Article. We could write:

class Asset
  def after_create
     case owner
     when User
       # send email
     when Article

But this is clumsy! When we have logic to express about the relationship between things, the Proxy is the right place for it. Anywhere else is just smearing logic throughout your code.

Proxy Extensions

Consider the following example:

has_many :assets do
  def to_s

You can actually extend your Proxy Objects with an Anonymous module! When you have logic that applies to a Collection of ActiveRecords, your has_many Proxy is probably the proper place for it. For example:

class Table
  has_many :cells do
    def to_matrix
      # convert from list to matrix form.

Another example of this technique is the following. Suppose an Asset as many Versions, such as small, medium, etc. We’d prefer a shorter way of finding the proper version of an Asset than saying asset.versions.find_by_name('thumbnail'), we’d like to just say asset.versions[:thumbnail]. Just define the brackets ([]) operator on the Proxy:

class Asset
  has_many :versions, :class_name => 'Asset', :foreign_key => :parent_id do
    def [](version_name)

Suppose we want to go one step further. If a particular version doesn’t exist, it shall be created on-the-fly:

def [](version_name)
  if version = find_by_name(version_name)
    # create a new version here.

Advanced Extensions

In some cases, we want to write generic Extensions–these should work regardless of the particular classes involved. In the context of a Proxy there are three methods you should be aware of: proxy_owner, proxy_target, and proxy_reflection.

Suppose we want to implement something like the build method, but one that doesn’t have the side effect of adding it to the owner in memory:

has_many :foo do
  def new(options = {}){proxy_reflection.primary_key_name =>}.merge(options))

Extensions are so useful–it just requires a little imagination–that I’m going to give one more example, this one apropos of Access Control:

class User
  has_many :draft_articles do
    def readable_by?(user)
      user == proxy_owner

Some Miscellany

  1. The has_one and belongs_to Proxies behave a bit oddly: here, cyclops.build_eye is used rather than the more obvious

  2. In general, has_one and belongs_to will shadow methods on the Target. Don’t name any database columns target or owner, for instance. This is one of the biggest complaints against the current implementation of Proxies!

  3. Both build and create will work even if the Proxy Owner is new. For example, u =;; In this example, both objects will be saved with the Foreign Key set correctly.

  4. Both build and create can take an array of attributes hashes. For example:[{...}, {...}]). This will build two assets at once. (This is quite nice where in a Controller you have a form that allows the upload of multiple Assets at once. The Controller code looks identical (in simple cases) regardless of whether the form allows a single or multiple upload!)

That’s the basic idea. In part II of this Article (to be released in the coming weeks), I will discuss ‘static’ Proxy methods and I will release version 0.1 of a new plugin that builds upon a lot of exciting work in this area. In the meantime, check this out.

  1. Dr Nic says:

    I did not know all that.

    I didn’t know has_many :my_assets, :class_name => 'Asset', :conditions => 'user_id = #{id}'

    Nor :after_add – this is cool.

    But the best thing I just learnt was proxy_owner – I’ve been wondering how to get access to the parent object inside an association method.


  2. Chris T says:

    Good article. The callbacks were news to me too.

    One thing I like about proxies to scope access is they tie in nicely with attr_protected.

    Something like the userid probably isn’t (or at least shouldn’t’ be) settable by mass assignment, so unless you use currentuser.assets you’d end up having to set the user_id separately. Uggh!

    Another case of Rails make the right thing look good too

  3. Wondering why you couldn’t find anything by searching for “proxy” in the the manual? Go gave a look at the section “Association Extensions” on ActiveRecord::Associations::ClassMethods.

  4. Joe Martinez says:

    Ditto on those callbacks – new info.

  5. Kamal Fariz says:

    I currently have proxies biting my ass. I have no idea what is causing Rails to just hand me the proxy, and never give me access to the actual associated object itself. For example, I have a Comment which belongsto a User. I have defined User#tos but doing comment.user.to_s will never work for some odd reason.

    My mind is boggled.

  6. nick kallen says:

    kamal — you have run into the shadowing issue I mentioned above. The easiest workaround is to extend the belongs to and define your own to_s which delegates to the proxy target

    belongs_to :user do
      def to_s

    Good luck

  7. Brian Takita says:

    I’m noticing that the proxy objects allow some nice opportunities to extract logic from the model class, which is nice for huge models.

  8. Mina Naguib says:

    In the second example, :other_assets will never work and will always return empty, since the :conditions you supply get AND-ed with the normal association, like so:

    SELECT * FROM assets WHERE (assets.userid = 1 AND (userid != 1))

  9. Nick Kallen says:

    Mina Naguib – absolutely correct, my example is terrible. I meant to illustrate the ridiculously awesome power of using single quotes in the conditions clause and came up with that contrived example which makes no sense. Sorry.

  10. Steven Hansen says:

    Awesome. Thanks, proxy_owner is exactly what I’ve been looking for!

Post a Comment

Your Information (Name required. Email address will not be displayed with comment.)

* Copy This Password *

* Type Or Paste Password Here *