New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
STI cast new instances to default type
on initialize.
#17169
Conversation
any update? |
Please don't ping in the issue tracker. It will be reviewed when someone have time and want to review. |
Apology for creating noise in the issue tracker but its been 3 months. So, it was just a gentle reminder. I will take care of it. |
No problem. Yeah, we are a lot behind the PRs schedule 😢. I'm trying to catch up, so expect this PR to being reviewed 🔜 😄 |
Thanks. 👍 |
I can verify that the added tests are correct and this is a fix for the issue. |
7d5fbb3
to
ec13fa3
Compare
Workaround: in the class at the top of the inheritance hierarchy:
(for those too lazy to run off a patch) :/ |
@kuldeepaggarwal can we try to make a copy of |
@senny Sure. will do it asap. Thanks for the hint. |
ec13fa3
to
e4e9dc6
Compare
Updated the PR. |
if subclass_from_attributes?(attrs) | ||
attrs = attrs.with_indifferent_access | ||
attrs[inheritance_column] ||= columns_hash[inheritance_column].default |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kuldeepaggarwal shouldn't this happen before if subclass_from_attributes?(attrs)
? Otherwise subclass_from_attributes?(attrs)
will not see the default.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are not actually seeing the defaults in subclass_from_attributes?(attrs)
,
def subclass_from_attributes?(attrs)
attribute_names.include?(inheritance_column) && attrs.is_a?(Hash)
end
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 sorry, my bad. Misread attribute_names
as attrs
@kuldeepaggarwal sorry for the long delay 😓. Finally got around to cleaning up my inbox. This doesn't apply cleanly on |
@senny: Sure, give me sometime. |
e4e9dc6
to
233425c
Compare
@senny Updated the PR.. 😄 |
end | ||
|
||
def subclass_from_attributes(attrs) | ||
attrs = attrs.to_h if attrs.respond_to?(:permitted?) | ||
subclass_name = attrs.with_indifferent_access[inheritance_column] | ||
subclass_name = (attrs || {}).with_indifferent_access[inheritance_column] || columns_hash[inheritance_column].default |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kuldeepaggarwal do we still need that ||
. Previous code was calling with_indifferent_access
directly, so that should never be nil
, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, actually in my previous commit I was initializing attrs ||= {}
so that's why I called with_indifferent_access
directly, which is equivalent to current implementation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah, I see. It's because we modify subclass_from_attributes?
in a weird way. Why not keep subclass_from_attributes?
as is but modify this part:
if subclass_from_attributes?(attrs)
subclass = subclass_from_attributes(attrs)
else
subclass = columns_hash[inheritance_column].default
end
This way the methods still do what their name suggests and it should be obvious at a glance how the subclass is determined.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We'd still have to do the find_sti_class(subclass_name)
though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Modified the implementation.
887e17d
to
835c30d
Compare
835c30d
to
6b18bdd
Compare
STI cast new instances to `default type` on initialize.
@kuldeepaggarwal thank you 💛 I made some modifications in the merge commit so that we can get rid of some duplicate conditionals. |
Awesome.. |
This will also get the defaults from attribute definitions like: attribute :type, :string, default: "SomethingElse"
Fixes issue described in rails#30399: A default value on the inheritance column prevented `child.becomes(Parent)` to return an instance of `Parent` as expected, instead it returns an instance of the default subclass. The change was introduced by rails#17169 and it was meant to affect initialization, alone. Where `Parent.new` is expected to return an instance of the default subclass.
fixes #17121