Add attribute_for_database attribute method#40456
Merged
kamipo merged 1 commit intorails:masterfrom Oct 30, 2020
Merged
Conversation
I've been reported an issue on enum from friends, they want a way to get mapped value, but currently there is no reliable way to get that value. If a record is loaded from database, `attribute_before_type_cast` works for that. but the attribute is changed by user, the attribute method won't work for that. ```ruby book = Book.new(status: "published") # returns "published", but what we really want is 2. book.status_before_type_cast ``` So I propose to add `attribute_for_database` attribute method, it consistently returns mapped value for enum.
2e1a189 to
1429893
Compare
tahsin352
approved these changes
Oct 26, 2020
|
@kamipo Just wondering : why didn't we try to fix type_cast_before_attribute to work with enum and instead created this new method? |
Member
Author
|
It is because returning "published" as a raw value is the expected behavior for the |
kamipo
added a commit
to kamipo/rails
that referenced
this pull request
Mar 22, 2021
Last year, I heard about the inconveniences of ActiveRecord Enum and got some feedback (one of those is rails#40456). Some people have reported that in practice they are using enums for user input and it is inconvenient to not be able to handle invalid input with validation like other attributes. Actually, a former colleague was overriding the attribute writer for validation, and they had wished this inconvenience to be resolved in the Rails. So I propose a way to add validation on the enum attribute. This allows people to no longer need to override the attribute writer. Before: ```ruby class Book < ActiveRecord::Base enum :status, [:proposed, :written] validates_inclusion_of :status, in: statuses.keys def status=(value) super rescue ArgumentError @attributes.write_cast_value("status", value) end end ``` After: ```ruby class Book < ActiveRecord::Base enum :status, [:proposed, :written], validate: true end ``` Resolves rails#13971.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
I've been reported an issue on enum from friends, they want a way to get
mapped value, but currently there is no reliable way to get that value.
If a record is loaded from database,
attribute_before_type_castworksfor that. but the attribute is changed by user, the attribute method
won't work for that.
So I propose to add
attribute_for_databaseattribute method, itconsistently returns mapped value for enum.
Originallyattribute_before_type_caston enum returned mapped value,but it was changed in Rails 5.0 (c51f9b6) to return user supplied raw
value.
I've been reported this issue from friends, they want a way to getmapped value, but currently that way remains lost.
So I propose to addattribute_for_databaseattribute method, itbehaves the same way as the previous
attribute_before_type_castforenum.