Skip to content

allow passing false to :polymorphic option of belongs_to#40879

Merged
kamipo merged 1 commit intorails:masterfrom
glaszig:fix-belongs-to-polymorphic
Dec 18, 2020
Merged

allow passing false to :polymorphic option of belongs_to#40879
kamipo merged 1 commit intorails:masterfrom
glaszig:fix-belongs-to-polymorphic

Conversation

@glaszig
Copy link
Contributor

@glaszig glaszig commented Dec 18, 2020

Summary

AR 6.1 will raise the following error because a condition would disregard the option :polymorphic entirely if false was passed.

ArgumentError: Unknown key: :polymorphic. Valid keys are:
:class_name, :anonymous_class, :primary_key, :foreign_key,
:dependent, :validate, :inverse_of, :strict_loading, :autosave,
:required, :touch, :counter_cache, :optional, :default

Other Information

i stumbled upon this using the awesome_nested_set gem.
it has options to configure polymorphism and always passes this option (with the default of false).

possibly related to #40830.

i added a test case. it's kind of weird though. please advise.

@glaszig
Copy link
Contributor Author

glaszig commented Dec 18, 2020

here's a single-file case with awesome_nested_set.

# frozen_string_literal: true

require "bundler/inline"

gemfile(true) do
  source "https://rubygems.org"

  git_source(:github) { |repo| "https://github.com/#{repo}.git" }

  gem "activerecord", "6.1.0"
  gem "sqlite3"
  gem "awesome_nested_set", require: false
end

require "active_record"
require "awesome_nested_set"

ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
ActiveRecord::Base.logger = Logger.new(STDOUT)

ActiveRecord::Schema.define do
  create_table :categories do |t|
    t.string :name
    t.integer :parent_id, null: true, index: true
    t.integer :lft, null: false, index: true
    t.integer :rgt, null: false, index: true
  end
end

class Category < ActiveRecord::Base
  acts_as_nested_set
end

Comment on lines 1359 to 1361
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

belongs_to :category on Category model is a bit weird.
Can you change the name to Post for example?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you move :polymorphic to the above line instead? It is always valid option regardless of the value.

diff --git a/activerecord/lib/active_record/associations/builder/belongs_to.rb b/activerecord/lib/active_record/associations/builder/belongs_to.rb
index 869b228dc7..584af2c3f2 100644
--- a/activerecord/lib/active_record/associations/builder/belongs_to.rb
+++ b/activerecord/lib/active_record/associations/builder/belongs_to.rb
@@ -7,8 +7,8 @@ def self.macro
     end
 
     def self.valid_options(options)
-      valid = super + [:counter_cache, :optional, :default]
-      valid += [:polymorphic, :foreign_type] if options[:polymorphic]
+      valid = super + [:polymorphic, :counter_cache, :optional, :default]
+      valid += [:foreign_type] if options[:polymorphic]
       valid += [:ensuring_owner_was] if options[:dependent] == :destroy_async
       valid
     end

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.

@glaszig glaszig force-pushed the fix-belongs-to-polymorphic branch from 10368e2 to e9adaea Compare December 18, 2020 05:30
before this, passing false would raise the following error
because a condition in AR would disregard the option entirely
if false was passed.

ArgumentError: Unknown key: :polymorphic. Valid keys are:
:class_name, :anonymous_class, :primary_key, :foreign_key,
:dependent, :validate, :inverse_of, :strict_loading, :autosave,
:required, :touch, :counter_cache, :optional, :default
@glaszig glaszig force-pushed the fix-belongs-to-polymorphic branch from e9adaea to 5b2332a Compare December 18, 2020 05:32
@kamipo kamipo merged commit 9c120d7 into rails:master Dec 18, 2020
@kamipo
Copy link
Member

kamipo commented Dec 18, 2020

Thanks!

kamipo added a commit that referenced this pull request Dec 18, 2020
allow passing false to :polymorphic option of belongs_to
@glaszig
Copy link
Contributor Author

glaszig commented Dec 18, 2020

for anybody coming across this and being in a hurry, i'm using this monkey patch:

# config/initializers/active_record.rb

module PolymorphicBelongsTo
  def valid_options(options)
    valid = super + [:polymorphic, :counter_cache, :optional, :default]
    valid += [:foreign_type] if options[:polymorphic]
    valid += [:ensuring_owner_was] if options[:dependent] == :destroy_async
    valid
  end
end

ActiveSupport.on_load :active_record do
  ActiveRecord::Associations::Builder::BelongsTo.extend PolymorphicBelongsTo
end

anitagraham added a commit to anitagraham/refinerycms-inquiries that referenced this pull request Jan 1, 2021
Add puma and selenium-webdriver to Gemfile.
Upgrade refinery version to 4.1.0 in gemspec
Leave Rails at 6.0.0 until 6.1 problem with polymorphic is released
(rails/rails#40879, includes a patch for
ActiveRecord in the comments)
Add rubocop fix for factory values

Minor changes to allow for matching first of several page elements and how to click on them.
anitagraham added a commit to anitagraham/refinerycms-inquiries that referenced this pull request Jan 22, 2021
   Changed recieved to received
   Add puma and selenium-webdriver to Gemfile.
   Upgrade refinery version to 4.1.0 in gemspec
   Leave Rails at 6.0.0 until 6.1 problem with polymorphic is released (rails/rails#40879, includes a patch for ActiveRecord in the comments)
   Add rubocop fix for factory values
   Spec changes to allow for matching first of several page elements and how to click on them.
   Work around a problem with polymorphism at Rails 6.0.3
   Use Rails credentials to store and retrieve recaptcha keys
   Include Refinery::Testing::ControllerMacros::Authentication through spec_helper, All tests pass
parndt added a commit to refinery/refinerycms-inquiries that referenced this pull request Jan 17, 2025
* Changed recieved to received
Add puma and selenium-webdriver to Gemfile.
Upgrade refinery version to 4.1.0 in gemspec
Leave Rails at 6.0.0 until 6.1 problem with polymorphic is released
(rails/rails#40879, includes a patch for
ActiveRecord in the comments)
Add rubocop fix for factory values

Minor changes to allow for matching first of several page elements and how to click on them.

* Try to get more specific error from Inquiries

* Work around a problem with polymorphism at Rails 6.0.3

* Use Rails credentials for recaptcha keys

* Add configuration for privacy_link
Add test gems/drivers as used for refinerycms
Testing:
  moved 'making_an_inquiry' into spec/support/spec_helper
  updated spec/spec_helper to match refinerycms

* Remove Rails 6.0.3 workaround

* Update rails dependency to ~>6.1

---------

Co-authored-by: Philip Arndt <git@p.arndt.io>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants