Skip to content
Permalink
Browse files
Defer loading of ActiveRecord to avoid config issues
If FriendlyId references `ActiveRecord::Base` while it is loading as
part of a Rails application, it triggers the `on_load` event for
ActiveRecord, which as part of the loading process sets the current
configuration values of ActiveRecord. If any initializers try to
influence that configuration (e.g. changing defaults in
`new_framework_defaults.rb` for an app that's been upgraded), these
changes will have no effect because the configuration has already been
set in place.

To avoid this, we need to avoid triggering the `on_load` event by
wrapping the reference to `ActiveRecord::Base` in an initializer
block. The simplest way of doing this is with a `Railtie`, which will
be automatically loaded if FriendlyId is required as part of Rails.

Fixes #823
  • Loading branch information
lazyatom authored and parndt committed Jan 15, 2018
1 parent a29e7d7 commit 4bd4300035b5c250aeb2e5feec4c2feb9bcf2a19
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 2 deletions.
@@ -4,6 +4,7 @@
require "friendly_id/object_utils"
require "friendly_id/configuration"
require "friendly_id/finder_methods"
require 'friendly_id/railtie' if defined?(Rails)

=begin
@@ -2,7 +2,6 @@ module FriendlyId
# Instances of these classes will never be considered a friendly id.
# @see FriendlyId::ObjectUtils#friendly_id
UNFRIENDLY_CLASSES = [
ActiveRecord::Base,
Array,
FalseClass,
Hash,
@@ -59,11 +58,15 @@ def unfriendly_id?
true
end
end

def self.mark_as_unfriendly(klass)
klass.send(:include, FriendlyId::UnfriendlyUtils)
end
end

Object.send :include, FriendlyId::ObjectUtils

# Considered unfriendly if object is an instance of an unfriendly class or
# one of its descendants.

FriendlyId::UNFRIENDLY_CLASSES.each { |klass| klass.send(:include, FriendlyId::UnfriendlyUtils) }
FriendlyId::UNFRIENDLY_CLASSES.each { |klass| FriendlyId.mark_as_unfriendly(klass) }
@@ -0,0 +1,9 @@
module FriendlyId
class Railtie < Rails::Railtie
initializer 'friendly_id.setup' do
ActiveSupport.on_load(:active_record) do
FriendlyId.mark_as_unfriendly(ActiveRecord::Base)
end
end
end
end
@@ -19,6 +19,8 @@ class ObjectUtilsTest < TestCaseClass
end

test "ActiveRecord::Base instances should be unfriendly_ids" do
FriendlyId.mark_as_unfriendly(ActiveRecord::Base)

model_class = Class.new(ActiveRecord::Base) do
self.table_name = "authors"
end

0 comments on commit 4bd4300

Please sign in to comment.