1

I'm running a Rails 2.3.14 app that is using a counter_cache column, something similar to:

Workshop
  belongs_to :group, :counter_cache => true

Group
  has_many :workshops

If I assign my workshop to a group directly, the counter cache is updated fine.

  @workshop.group = Group.first
  @workshop.save # group counter updated

However, if I mass-assign a group_id to the workshop, in the traditional Rails controller style, the cache is NOT updated. I take this to be a bug in 2.3.14.

  def update
    @workshop = Workshop.find(params[:id])

    # params[:workshop] contains a group_id assignment, thus the problem
    if @workshop.update_attributes(params[:workshop])
      flash[:notice] = 'Workshop was successfully updated.'
      # @workshop.group counter NOT updated

It also exists in older versions: http://railsforum.com/viewtopic.php?id=34473

However, the poster's "solution" introduces a double-counting bug - if you assign directly, you'll get the default rails updater and the callback-one, but it does work for update_attributes.

So, I can do a couple of things - I can strip out the group_id out of the params hash and assign it directly. Or I can monkey-patch update_attributes on my Workshop model to do this for me.

I'd like to avoid stripping out the params hash as that's not intuitive and self-documenting, further anyone else who may call @workshop.update_attributes would encounter the same bug. Monkey-patching update_attributes seems safest but also totally, horribly wrong.

Any other suggestions?

Thanks!

Matt Rogish
  • 24,435
  • 11
  • 76
  • 92

1 Answers1

1

Would using Group.update_counters(params[:workshop][:group_id], :workshops_count => +1) or something similar work?

Found a good resource that fixed my issue which is similar to yours via Josh Owens. Also, Rails api has some info as well. In my case, using your names, I want to move a workshop from one group to another and have the counters update appropriately.