About

James Golick

James Golick is an engineer, entrepreneur, speaker, and above all else, a grinder.

As CTO (or something?) of BitLove, he scaled FetLife.com's traffic by more than an order of magnitude (and counting).

James spends most of his time writing ruby and scala, building infrastructure, and extinguishing fires.

He speaks regularly at conferences and blogs periodically, but James values shipping code over just about anything else.

Latest Tweets

follow me on Twitter

James on the Web

association_proxy.is_a?(Array), acts like an array, but doesn't save like an array

Sep 26 2007

So, how many times have you had the urge to write:
@post.comments.reject!(&:spam?)
@post.save
Lots? Me too. So, I think it's worth clearing the air on our good friend association proxy. He really, really wants you to believe he's an array. He'll even tell you he is.
assert @post.comments.is_a?(Array)
But, don't believe him, because a lot of his array functionality is useless to us. Your favourite rubyisms (reject!, select!, etc) will modify the collection, but will not modify the associations. This test passes:
def test_association_proxy_really_looks_like_an_array_but_it_isnt
  assert Post.find(1).comments.is_a?(Array)
  
  assert Post.find(1).comments.select(&:spam?).length > 0
    
  post = Post.find(1)
  post.comments.reject!(&:spam?)
  post.save!
  
  assert_equal [], post.comments.select(&:spam?)
  assert Post.find(1).comments.select(&:spam?).length > 0
end
Instead, of course, you have to use the delete method.
post.comments.delete(post.comments.select(&:spam?))
Association proxy is tricky.