The Artima Developer Community
Sponsored Link

Ruby Buzz Forum
Appending to an association more efficiently

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Obie Fernandez

Posts: 608
Nickname: obie
Registered: Aug, 2005

Obie Fernandez is a Technologist for ThoughtWorks
Appending to an association more efficiently Posted: Dec 21, 2006 5:21 PM
Reply to this message Reply

This post originated from an RSS feed registered with Ruby Buzz by Obie Fernandez.
Original Post: Appending to an association more efficiently
Feed Title: Obie On Rails (Has It Been 9 Years Already?)
Feed URL: http://jroller.com/obie/feed/entries/rss
Feed Description: Obie Fernandez talks about life as a technologist, mostly as ramblings about software development and consulting. Nowadays it's pretty much all about Ruby and Ruby on Rails.
Latest Ruby Buzz Posts
Latest Ruby Buzz Posts by Obie Fernandez
Latest Posts From Obie On Rails (Has It Been 9 Years Already?)

Advertisement

Rails changeset 5769 makes a pretty big change to the behavior of the << method on association collections. Pushing a record on an association collection doesn't unnecessarily load all the associated records anymore, which at least some people consider a major performance concern. I'm not sure yet if this change will be included in Rails 1.2

If you're not running EdgeRails, what can you do to establish a relationship using existing objects, without taking the aforementioned performance hit?

The answer is that you have to write your own little custom method for the association, basically a much simpler version of the built-in << method. Luckily it's very simple to do that, by using the ability to define extension methods in a block argument to the association.

First, open up association_collection.rb and take a look at the current implementation of the << method, which looks something like this (prior to revision 5769):

def <<(*records)
  result = true
  load_target

  @owner.transaction do
    flatten_deeper(records).each do |record|
      raise_on_type_mismatch(record)
      callback(:before_add, record)
      result &&= insert_record(record) unless @owner.new_record?
      @target << record
      callback(:after_add, record)
    end
  end

  result && self
end

Using the existing implementation as a starting point, you can pick and choose the lines that you want to include in your method. Most importantly, leave out the call to load_target!

In my example implementation, I chose to execute inside of a transaction, insert the join-table record, append the new record to @target (the association collection), and return self. Here is the code (and keep in mind that I left of the other options to habtm for the sake of clarity):

has_and_belongs_to_many :related do
  def associate(record)
    @owner.transaction do
      insert_record(record) unless @owner.new_record?
      @target << record
    end
  end
  self
end

Disclaimers: The example is not taken from production code and your mileage may vary. This won't work for has_many :through associations. Also, it's not really necessary to worry about this unless you have large collections of related objects.

Thanks to Jeremy for making this change happen!

Read: Appending to an association more efficiently

Topic: Create a mesh network in your neighborhood Previous Topic   Next Topic Topic: How fast will it go?

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use