Associations oddity

Can anyone explain this oddity to me?

Given two classes as follows:

class Question < ActiveRecord::Base
belongs_to :category
end

class Category < ActiveRecord::Base
has_many :questions
end

I get the following:

q = Question.find 6789
=> #<Question:0x37e9e70 @attributes={“id”=>“6789”,
“category_id”=>“8200”}>

cat = q.category
=> #<Category:0x37e1cc8 @attributes={“id”=>“8200”}>

q.category = nil
=> nil

cat
=> nil

The last line is the bit that’s confusing me.

I can “fix” it as follows:

q = Question.find 6789
=> #<Question:0x37e9e70 @attributes={“id”=>“6789”,
“category_id”=>“8200”}>

cat = q.category.dup
=> #<Category:0x37e1788 @attributes={“id”=>“8200”}>

q.category = nil
=> nil

cat
=> #<Category:0x37e1788 @attributes={“id”=>“8200”}>

But why do I need the “dup”? This seems to break the principle of least
surprise? Is there a better way to handle this?

Thanks in advance for your help!

paul.butcher->msgCount++

Snetterton, Castle Combe, Cadwell Park…
Who says I have a one track mind?

This looks very strange, doesn’t it?

What happens is that when you call

q.category

you get AssociationProxy object which pretends to be another object.
After you call

q.category = nil

this proxy pretends to be a nil object. You can see it by inspecting
the object id like

puts cat.id

It should return something other than value 4 which is an id of the nil
object.

Kent.