Suspeito que o ActiveRecord não esteja percebendo que seus
friends
array mudou porque, bem, a referência de array subjacente não muda quando você:self.friends.push(target)
Isso alterará o conteúdo da matriz, mas a matriz em si ainda será a mesma matriz. Eu sei que esse problema surge com a gem postgres_ext no Rails3 e dado este problema:
O atributo String não é marcado como sujo quando é alterado com<<
Eu esperaria que Rails4 se comportasse da mesma maneira.
A solução seria criar uma nova matriz em vez de tentar modificar a matriz no local:
update_attributes friends: self.friends + [ target ]
Existem muitas maneiras de criar um novo array enquanto adiciona um elemento a um array existente, use o que você quiser.