In response to this issue, I submitted this github issue: Rails where query should see value is an enum and convert a string #17226
?
or a named param, but I suspect that a quick map lookup to see that the attribute is an enum, and a string is passed, and then converting the string value to an integer is the right thing to do for 2 reasons:find_or_initialize_by
and find_or_create_by
will result in obscure bugs when string params are passed for enums.However, it’s worth considering if all default accessor methods (setters) should be consistently be called for purposes of passing values in a map to such methods. I would venture that Rails enums are some Rails provided magic, and thus they should have a special case. If this shouldn’t go into Rails, then possibly a gem extension could provide a method like Model.where_with_enum
which would convert a String into the proper numerical value for the enum. I’m not a huge fan of the generated Model scopes for enums, as I like to see what database field is being queried against.
Integer(some_string)
rather than some_string.to_i
. The difference is considerable, String#to_i
is extremely permissive. Try it in a console. With the to_i
method, any number characters at the beginning of the String are converted to an Integer. If the first character is not a number, 0 is returned, which is almost certainly a default enum value. Thus, this simple change would make it extremely clear when an enum string is improperly used. I would guess that this would make some existing code crash, but in all circumstances for a valid reason. As to whether this change should be done for all integer attributes is a different discussion, as that could have backwards compatibility ramifications. This change would require changing the tests in ActiveRecord::ConnectionAdapters::TypesTest. For example, this test:would change to throw an exception, unless the cases are restricted to using Integer.new() for enums. It is inconsistent that some type conversions throw exceptions, such as converting a symbol to an integer. Whether or not they should is much larger issue. In the case of enums, I definitely believe that proper enum string value should not silently convert to zero every time.
Hi Stefano,Thanks for your comments. I would have contributed a PR, but I didn't get any suggestion from the core members that this would make sense. It seems like they are working on something for Rails 5.Consider posting: http://forum.railsonmaui.com/t/enums-and-queries-in-rails-4-1-and-understanding-ruby/118/6Aloha,Justin
--
You received this message because you are subscribed to a topic in the Google Groups "Ruby on Rails: Core" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/rubyonrails-core/Ot-rSeo2Yvk/unsubscribe.
To unsubscribe from this group and all its topics, send an email to rubyonrails-co...@googlegroups.com.
To post to this group, send email to rubyonra...@googlegroups.com.
Visit this group at http://groups.google.com/group/rubyonrails-core.
For more options, visit https://groups.google.com/d/optout.
Thank you both for this conversation.
I thought of bringing up in this thread a few points related to conversations such as: https://github.com/rails/rails/issues/13971
Is there any plan to make enum so that it can be used 'to expose user-facing attributes' ?
It would be really awesome to use this kind of optimizations not just for managing the internal states of the application.
Thank you for the awesome work
Stefano
On Friday, October 24, 2014 at 12:40:31 AM UTC+2, Nicholas Firth-McCoy wrote:
--
You received this message because you are subscribed to a topic in the Google Groups "Ruby on Rails: Core" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/rubyonrails-core/Ot-rSeo2Yvk/unsubscribe.
To unsubscribe from this group and all its topics, send an email to rubyonrails-co...@googlegroups.com.
To post to this group, send email to rubyonra...@googlegroups.com.
Visit this group at http://groups.google.com/group/rubyonrails-core.
For more options, visit https://groups.google.com/d/optout.