diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 44cb8537bd8b0f808b0a18026eb28771f2e8b116..1644f80d743d999e99b9a6e5aff9be06cacefe65 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,12 @@ +* ActiveRecord's `belongs_to_required_by_default` flag can now be set per model. + + You can now opt-out/opt-in specific models from having their associations required + by default. + This change is meant to ease the process of migrating all your models to have + their association required. + + *Edouard Chin* + * The `connection_config` method has been deprecated, please use `connection_db_config` instead which will return a `DatabaseConfigurations::DatabaseConfig` instead of a `Hash`. *Eileen M. Uchitelle*, *John Crepezzi* diff --git a/activerecord/lib/active_record/core.rb b/activerecord/lib/active_record/core.rb index 435416055ffbd1072445f554fc8a48ccf0bbe330..8a97da626370497cbc8cbd64b331dbd017e00af0 100644 --- a/activerecord/lib/active_record/core.rb +++ b/activerecord/lib/active_record/core.rb @@ -120,7 +120,7 @@ def self.configurations mattr_accessor :maintain_test_schema, instance_accessor: false - mattr_accessor :belongs_to_required_by_default, instance_accessor: false + class_attribute :belongs_to_required_by_default, instance_accessor: false mattr_accessor :connection_handlers, instance_accessor: false, default: {} diff --git a/activerecord/test/cases/associations/belongs_to_associations_test.rb b/activerecord/test/cases/associations/belongs_to_associations_test.rb index 6bd305306f184797988115a5d6acb92e8e9178e7..168a4744eba6a34e00cb7bc0825818f322d1f512 100644 --- a/activerecord/test/cases/associations/belongs_to_associations_test.rb +++ b/activerecord/test/cases/associations/belongs_to_associations_test.rb @@ -84,6 +84,33 @@ def test_belongs_to_with_primary_key_joins_on_correct_column end end + def test_optional_relation_can_be_set_per_model + model1 = Class.new(ActiveRecord::Base) do + self.table_name = "accounts" + self.belongs_to_required_by_default = false + + belongs_to :company + + def self.name + "FirstModel" + end + end.new + + model2 = Class.new(ActiveRecord::Base) do + self.table_name = "accounts" + self.belongs_to_required_by_default = true + + belongs_to :company + + def self.name + "SecondModel" + end + end.new + + assert_predicate model1, :valid? + assert_not_predicate model2, :valid? + end + def test_optional_relation original_value = ActiveRecord::Base.belongs_to_required_by_default ActiveRecord::Base.belongs_to_required_by_default = true diff --git a/guides/source/upgrading_ruby_on_rails.md b/guides/source/upgrading_ruby_on_rails.md index 8eb9984872bf77dcaab67f973aa1cb2ae91d803f..d0872500fd91878a1a6715f59a02ac4faa526ae7 100644 --- a/guides/source/upgrading_ruby_on_rails.md +++ b/guides/source/upgrading_ruby_on_rails.md @@ -845,6 +845,26 @@ want to add this feature it will need to be turned on in an initializer. config.active_record.belongs_to_required_by_default = true +The configuration is by default global for all your models, but you can +override it on a per model basis. This should help you migrate all your models to have their +associations required by default. + + ```ruby + class Book < ApplicationRecord + # model is not yet ready to have its association required by default + + self.belongs_to_required_by_default = false + belongs_to(:author) + end + + class Car < ApplicationRecord + # model is ready to have its association required by default + + self.belongs_to_required_by_default = true + belongs_to(:pilot) + end + ``` + #### Per-form CSRF Tokens Rails 5 now supports per-form CSRF tokens to mitigate against code-injection attacks with forms