Skip to content

Instantly share code, notes, and snippets.

@curtis
Created May 20, 2015 18:22
Show Gist options
  • Save curtis/ef068bc04e5fc859c8ea to your computer and use it in GitHub Desktop.
Save curtis/ef068bc04e5fc859c8ea to your computer and use it in GitHub Desktop.
Initializer file to help patch Rails 3.2.* has_many associations when using Ruby 2.2. See https://github.com/rails/rails/issues/18991
# For Rails 3.2.*
#
if Rails.version =~ /^3.2/
# The call to has_cached_counter? throws an exception on the 3.2.* version of rails.
# See https://github.com/rails/rails/issues/18991
ActiveRecord::Associations::HasManyThroughAssociation.class_eval do
def size
if has_cached_counter?(reflection)
owner.send(:read_attribute, cached_counter_attribute_name)
elsif loaded?
target.size
else
count
end
end
def insert_record(record, validate = true, raise = false)
ensure_not_nested
if record.new_record?
if raise
record.save!(:validate => validate)
else
return unless record.save(:validate => validate)
end
end
save_through_record(record)
update_counter(1, reflection)
record
end
end
ActiveRecord::Associations::HasManyAssociation.class_eval do
private
def count_records
count = if has_cached_counter?(reflection)
owner.send(:read_attribute, cached_counter_attribute_name)
elsif options[:counter_sql] || options[:finder_sql]
reflection.klass.count_by_sql(custom_counter_sql)
else
scoped.count
end
# If there's nothing in the database and @target has no new records
# we are certain the current target is an empty array. This is a
# documented side-effect of the method that may avoid an extra SELECT.
@target ||= [] and loaded! if count == 0
[options[:limit], count].compact.min
end
end
end
@curtis
Copy link
Author

curtis commented May 20, 2015

Hopefully this will help people that are unable to upgrade off Rails 3.2.*, but want to use Ruby 2.2 (it happens ;). There probably won't be any additional updates on the 3.2 branch, so patching may be your best/only option.

The relevant error message seen for this problem, with last 4 of stack trace, is:

NoMethodError - undefined method `name' for nil:NilClass:
activerecord (3.2.19) lib/active_record/associations/has_many_association.rb:58:in `cached_counter_attribute_name'
activerecord (3.2.19) lib/active_record/associations/has_many_association.rb:54:in `has_cached_counter?'
activerecord (3.2.19) lib/active_record/associations/has_many_association.rb:62:in `update_counter'
activerecord (3.2.19) lib/active_record/associations/has_many_through_association.rb:53:in `insert_record'

FMI, see rails/rails#18991

There are really only 3 changes here to patch activerecord (lines 8, 29 and 39), where we explicitly pass reflection to has_cached_counter? and update_counter

Feel free to offer up suggestions!

@curtis
Copy link
Author

curtis commented May 20, 2015

Another option is to upgrade to the latest stable branch version for 3.2:

gem 'rails', github: 'rails/rails', branch: '3-2-stable'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment