Posted this on SO: http://stackoverflow.com/questions/11889922/rails-append-not-adding-object-to-has-many-through
I'm getting weird behavior when trying to add objects via a has_many :through relationship.
Class Player < ActiveRecord::Base
has_many :team_histories, through: :player_to_team_histories
Class TeamHistory < ActiveRecord::Base
has_many :players, through: :player_to_team_histories
>>p = Player.first
>>p.team_histories << TeamHistory.create
Why does append not add the newly created TeamHistory to the team_histories array?
I'm using Ruby 1.9.2.
There is no documentation about the append method for ActiveRecord. Was append intentionally left out?
I've always used <<, so I'm not sure what's right here. /cc @tenderlove @jonleighton
append and prepend are Array aliases do << and unshift, respectively, see 9482554.
>> .append 2
NoMethodError: undefined method 'append' for :Array
>> require 'active_support/all'
>> .append 2
This means that, when they're called on the association like that, they're just being delegated to Array, so they do not work with the association.
Perhaps - but just perhaps - we should add aliases to the proxy as well, since we added them to the Array, but I'd like to see other thoughts on that first.
@carlosantoniodasilva - there's already code to do this for Array#push:
On the other hand, I'm not at all sure what we should do about prepend, also added by ActiveSupport. Is there an equivalent to Array#unshift that makes sense?
I suppose if we're going to monkey patch array to have this behavior, we should make it consistent everywhere. Changing the alias method to a delegate method would probably fix this as well:
def append(*args); self.<<(*args); end
When adding new records to an association we currently don't differentiate between append/prepend. I see the following options:
I'm for option 3 to prevent further confusion. Let me know what you think and I'll submit a PR.
@tenderlove the delegation won't fix the problem since the proxy will delegate append to the target (the Array) and then << is called on the Array not on the proxy.
I submitted a PR with an implementation for 3.)