David StevensonDavid Stevenson
Standup 09/26/2008: proxy_target vs load_target
edit Posted by David Stevenson on Friday September 26, 2008 at 04:49PM

Interesting Things

  • When defining an extension to an association, you can access the loaded association data through proxy_target. If the data hasn't been preloaded/loaded when you call this method, it will return []. If you'd like to manually load the target, you can call load_target, and you can call loaded to determine if the proxy data has been loaded. For most situations, however, you can rely on the association to load itself when necessary by calling methods on self as follows:
has_many :people do
  def bad_people
    self.select {|person| person.bad? }
  end

  # exact same situation as 'bad_people', but 2x worse code
  def good_people
    load_target unless loaded?
    proxy_target.select {|person| !person.bad? }
  end
end
  • There's no good way to use CSV fixtures and has_and_belongs_to_many associations, in such a way that they are easily understandable and editable by non-technical people. Foxy fixtures solved a lot of issues with fixtures, but those advantages only work with YAML fixtures. Hence, if you have a HABTM situation, you're stuck building a lot of rows of CSV referencing arbitrarily chosen IDs across several different files.

Comments

  1. Cameron Booth Cameron Booth on September 28, 2008 at 02:42PM

    I've always used association extensions almost as nested named_scopes, like this:

    has_many :people do
      def bad_people
        find(:all, :conditions => {:bad => true})
      end
    end
    

    I suppose that could be beefed up to use the full association if it's been loaded, something like this maybe:

    has_many :people do
      def bad_people
        if loaded?
          self.select{|person| person.bad?}
        else
          find(:all, :conditions => {:bad => true})
        end
      end
    end
    

    The benefit there is that you're not loading all objects from the database if you don't need them, only the bad people. Any drawbacks that I'm not thinking of with this approach?

Add a Comment (MarkDown available)