Require belongs_to by default.#18937
Conversation
63a04a1 to
66c389b
Compare
|
I wonder what to do with failing test. This code fails now, since belongs_to relation is required by default. Should I change generated test for belongs_to to make it pass or should I remove this test since it is not valid with this change? |
There was a problem hiding this comment.
Better info will be needed here. Any ideas?
There was a problem hiding this comment.
'required: true is now the default for belongs_to and can be removed.' – don't even need to talk about optional here. What they wanted to do is now being done for them.
There was a problem hiding this comment.
What about when required: false is specified explicitly? Maybe throw deprecation warning only for false value?
There was a problem hiding this comment.
That was the old default, which means no client code will have that code, since it doesn’t make any sense.
On Feb 15, 2015, at 12:54 PM, Josef Šimánek notifications@github.com wrote:
In activerecord/lib/active_record/associations/builder/belongs_to.rb #18937 (comment):
@@ -110,5 +110,24 @@ def self.add_destroy_callbacks(model, reflection)
name = reflection.name
model.after_destroy lambda { |o| o.association(name).handle_dependency }
end
+
- def self.define_validations(model, reflection)
if reflection.options.key?(:required) What about when required: false is specified explicitly? Maybe throw deprecation warning only for false value?ActiveSupport::Deprecation.warn('`required` option for belongs_to relation is deprecated and replaced with `optional` option.')—
Reply to this email directly or view it on GitHub https://github.com/rails/rails/pull/18937/files#r24725940.
66c389b to
b60ef6b
Compare
|
You can kill that test and replace it with a test that tests optional: true.
|
|
Should I add also this to generator? |
|
Nah, don’t think that’s necessary. Will be a very uncommon option to use, I think.
|
2494879 to
c134970
Compare
|
OK I think my work is almost done here. I'll add also CHANGELOG note soon. |
|
Awesome. Ping when ready to merge.
|
8d17afe to
03ef4b4
Compare
|
I added CHANGELOG note, but it is a little fuzzy to me. Feel free to ping me with better one. |
There was a problem hiding this comment.
Let's try with:
belongs_to will now trigger a validation error by default if the association is not present. You can turn this off on a per-association basis with optional: true. (Note this new default only applies to new Rails apps that will be generated with config.active_record.require_belongs_to = true)
There was a problem hiding this comment.
Actually the final note is not true right now. config.active_record.require_belongs_to = true is set directly in railtie, not in application config. Should I move it to new generated application.rb and let it nil for existing applications? In that case your note will be true.
|
Let's update the config option to be a bit clearer: |
|
This is also missing the config/initializers/active_record_belongs_to_required_by_default.rb file that's going to set the |
|
@dhh I mentioned that https://github.com/rails/rails/pull/18937/files#r24953865 already. |
|
Ah, we crossed streams. Didn't note that one. Yes, please do go ahead. Thanks! |
There was a problem hiding this comment.
I'm finding the control flow here a little difficult to follow. Consider condensing the conditionals and using the :optional option to determine whether to declare the presence validation:
# Disallow conflicting options
if reflection.options.key?(:required) && reflection.options.key?(:optional)
raise ArgumentError, "complain if we have conflicting options"
# Deprecate :required
elsif reflection.options.key?(:required)
reflection.options[:optional] = !reflection.options[:required]
ActiveSupport::Deprecation.warn "switch to `optional: #{reflection.options[:optional]}`"
# Set default :optional option
elsif !reflection.options.key?(:optional)
reflection.options[:optional] = !model.require_belongs_to
end
super
if !reflection.options[:optional]
model.validates_presence_of …
end|
Nice work @simi. Pardon the repeated remarks, looks like I missed concurrent feedback too. Thanks! |
|
Nevermind @jeremy. Thanks for review. I have just one more question. I made change where |
|
I bet it will be better as initializer after inspecting currently generated initializers. |
|
@jeremy @dhh I pushed new commit (I can squash later, just to highlight new code). This initializer is generated only when |
The referenced change for rails 5 is making the belongs_to relationships break validations for our models. This change makes them optional. rails/rails#18937
Since rails#18937 `belongs_to` associations implies `required: true` by default, with that option replaced for `optional: false`.
Since rails#18937 `belongs_to` associations receive a setting to determine if it should be or not treated as `required` by default. While the tests were still passing, it was not evident that the "default" behaviour for `required` could change in fuction of a setting, that is set by default for fresh Rails5 apps, but not for upgraded apps. This commit try to relate them to make it clear what is the behaviour expected when the setting is set as `true` or not set.
|
I feel this change was a bit of a mistake at the design level... validations and relations are different things, and now we get validations done when defining relations. I understand the "it's convenient" argument tho. |
|
|
||
| ##### `:optional` | ||
|
|
||
| If you set the `:optional` option to `true`, then associated object will be validated for presence. By default, this is `false`: associated objects will be validated for presence. |
There was a problem hiding this comment.
Typo: "then associated object will NOT be validated for presence"
There was a problem hiding this comment.
optional: By default, this is false: associated objects will be validated for presence.
There was a problem hiding this comment.
I'm talking about the first part. Look more closely, the sentence says the same thing twice:
If you set the `:optional` option to `true`, then associated object
will be validated for presence. By default, this is `false`: associated objects
will be validated for presence.
I took the original sentence and just modified the alignement so it's visually clear they are the same.
The referenced change for rails 5 is making the belongs_to relationships break validations for our models. This change makes them optional. rails/rails#18937
|
We are only testing for validation of the presence of the association ID, what if the given ID is invalid. And app behaviour is not to validate the existence of such association? |
…is required by default in rails 5. (rails/rails#18937)
…is required by default in rails 5. (rails/rails#18937) Revert all followers to old implementation
Deprecate
requiredoption in favor ofoptionalforbelongs_to.closes #18233