Bounty of $25 for the first working solution.
I'm seeing a really weird has_many :through problem with ActiveRecord.
With these classes:
create_table :numbers do |t|
t.string :phone_number
end
create_table :call_lists do |t|
t.string :type
t.string :name
t.integer :user_id
t.integer :county_id
t.integer :state_id
end
create_table :call_list_memberships do |t|
t.integer :call_list_id
t.integer :number_id
end
class CallList < ActiveRecord::Base
attr_accessible :name
has_many :call_list_memberships, :autosave => true
has_many :numbers, :through => :call_list_memberships, :autosave => true
belongs_to :user
end
class PoliticalDistrict < CallList
end
class CallListMembership < ActiveRecord::Base
belongs_to :call_list
belongs_to :number
end
class Number < ActiveRecord::Base
attr_accessible :phone_number
has_many :call_list_memberships
has_many :call_lists, :through => :call_list_memberships
end
I get this behaviour:
>> p1 = PoliticalDistrict.first
=> #<PoliticalDistrict id: 2, type: "PoliticalDistrict", name: "Random political district", user_id: nil, county_id: nil, state_id: nil>
>> p1.numbers
=> []
>> p1.call_list_memberships
=> []
>> n1 = Number.first
=> #<Number id: 1, phone_number: "07921088939">
>> p1.numbers << n1
=> [#<Number id: 1, phone_number: "07921088939">]
>> p1.numbers
=> [#<Number id: 1, phone_number: "07921088939">]
>> p1.call_list_memberships
=> [#<CallListMembership id: 6, call_list_id: 2, number_id: nil>, #<CallListMembership id: 6, call_list_id: 2, number_id: nil>]
>> p1.save
=> true
Adding an object to the :through collection appears to add two items to the root association, both missing the ID of the object added.
Does anyone have any ideas why this might be happening?
Edit: Even this doesn't work:
>> pd2.call_list_memberships.create :number => Number.first
=> #<CallListMembership call_list_id: 2, number_id: nil>
>> Number.first
=> #<Number id: 1, phone_number: "07921088939">
>> pd2.call_list_memberships
=> [#<CallListMembership call_list_id: 2, number_id: nil>]
Ok, so after a long and rather frustrating search for the answer to this, I finally tracked down the issue and it's a damned embarrassing one.
I was using the following dynamic attr_accesssible code in an initializer:
class ActiveRecord::Base
attr_accessible
attr_accessor :accessible
private
def mass_assignment_authorizer
if accessible == :all
self.class.protected_attributes
else
super + (accessible || [])
end
end
end
Which I had conveniently forgotten about and which caused number_id to be inaccessible (thanks to the empty attr_accessible call).