selections, updates and counter caches

Hi All,

Just wondered how you are meant to get around this little issue:

I have a Company model, which has_many :people and I keep track of the number with a counter cache:

class Company < ActiveRecord::Base   has_many :people end

class Person < ActiveRecord::Base   belongs_to :company, :counter_cache => true end

Creating new records, deleting them and reassigning people to new companies all works fine.

However, I have a form to edit people which includes a selection list to pick the company: (in /people/edit.html.erb) <%= collection_select(:person, :company_id, @companies, :id, :name, {:prompt => true}) %>

Now here's the killer - Since the controller updates the attributes the company_id is changed but the counter cache is NOT:

      if @person.update_attributes(params[:person])         flash[:notice] = 'Person was successfully updated.'         format.html { redirect_to(people_path) }         format.xml { head :ok }       else

Of course, changing the company through the association works perfectly, so the work around is to do something like the following:

      @person.company = Company.find params[:person][:company_id]       if @person.update_attributes(params[:person])         flash[:notice] = 'Person was successfully updated.'

For extra security and peace of mind, it should also pay to make the company_id field in the People model protected (rather than readonly, which would allow the instance to be out of step with the database):

class Person < ActiveRecord::Base   belongs_to :company, :counter_cache => true   attr_protected :company_id end

I would submit a patch to do this automatically for all counter caches, but it is beyond my abilities at the moment.