-
Notifications
You must be signed in to change notification settings - Fork 21.6k
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
Fix enum writers when using integers #13542
Conversation
@@ -62,7 +67,7 @@ def enum(definitions) | |||
_enum_methods_module.module_eval do | |||
# def status=(value) self[:status] = STATUS[value] end | |||
define_method("#{name}=") { |value| | |||
unless enum_values.has_key?(value) | |||
if !enum_values.has_key?(value) && !enum_values.has_value?(value) |
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 can change this to unless (enum_values.has_key?(value) && enum_values.has_value?(value))
to avoid double negation.
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, I should revert it back, the other tests fail if we change this.
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.
De Morgan's law is your friend :)
This would be !(enum_values.has_key?(value) || enum_values.has_value?(value))
but I actually prefer the version you have now anyway - much easy to read and hurts my brain less.
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.
Nvm! That's basically the same thing @vipulnsward said :P (Every time I read unless x && y || z ...
my head still hurts a little)
Thanks for your feedback @vipulnsward, updated! |
Previously, the writer methods would simply check whether the passed argument was the symbol representing the integer value of an enum field. Therefore, it was not possible to specify the numeric value itself but the dynamically defined scopes generate where clauses relying on this kind of values so a chained call to a method like `find_or_initialize_by` would trigger an `ArgumentError`. Reference #13530
Add a mention about the automatic generation of scopes based on the allowed values of the field on the enum documentation.
Fix enum writers when using integers
Previously, this would give an `ArgumentError`: class Issue < ActiveRecord::Base enum :status, [:open, :finished] end Issue.open.build # => ArgumentError: '0' is not a valid status Issue.open.create # => ArgumentError: '0' is not a valid status PR #13542 muted the error, but the issue remains. This commit fixes the issue by allowing the enum value to be written directly via the setter: Issue.new.status = 0 # This now sets status to :open Assigning a value directly via the setter like this is not part of the documented public API, so users should not rely on this behavior. Closes #13530.
Hello,
This is just a little pull request that resolves some issues mentioned in #13530. Basically, the problem is described in this gist. Previously, a call to:
Would fail (an
ArgumentError
would be raised) because only the symbol version of the enum was checked when calling its writer method. I guess thatfind_or_initialize
is calling it through theinitialize
(new) method.I also added a mention about the scopes generated dynamically based on the allowed values of the field in the documentation.
I'm not really comfortable with Active Record and its internals so I'm certainly not very clear ; therefore, sorry. Let me know if I should update anything.
By the way, the issue mentioned above is not totally resolved since the
where
method doesn't generate the same queries with either a symbol or a numeric value on enum fields.Have a nice day.