1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Make belongs_to_required_by_default a class attribute:

- I'm hoping to get this change accepted even though this flag was
  introduced years ago in 6576f7354e

  My use case is the following:

  We were never enforcing belongs to association and we have a lot
  of models that implicitely declare an association as optional.
  We are now changing all our models to make associations required
  by default.
  Since we have a lot of models (more than 1000), I'd like to
  progressively enable them to use the `belongs_to_required_by_default`
  flag.

  The problem is that this flag is a mattr_accessor and doesn't to be
  set per model. We basically need to modify all our models (which
  could take years) before being able to modify the global flag.

  I'd like to change this flag to a class_attribute to solve the
  issue.
This commit is contained in:
Edouard CHIN 2019-12-17 18:07:29 +01:00
parent f8bda7c5e4
commit f2873d596d
4 changed files with 57 additions and 1 deletions

View file

@ -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*

View file

@ -120,7 +120,7 @@ module ActiveRecord
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: {}

View file

@ -84,6 +84,33 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
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

View file

@ -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