I definitely agree that there are some 'gotchas' here.

I can't think of any disadvantages to switching to using `Integer()` 
instead of `to_i` - as you say, this would only raise an exception in 
instances where the user has a bug in their code, which is a good thing to 
discover. I don't think we could change this elsewhere though.

I also think having a new scope for the enum generated such as `Conversation
.with_status(string_or_num_status)` would be a nice helper in cases where 
you have a dynamic value as it lets you avoid the alternative 
`Conversation.send(@some_conversation.status)` or 
`Conversation.where(status: 
Conversation.statuses(@some_conversation.status))`.

On Thursday, October 23, 2014 7:02:27 AM UTC+11, Justin Gordon wrote:
>
> I wrote up this detailed description of the issues I'm having with Rails 
> Enums:
>
> Enums and Queries in Rails 4.1, and Understanding Ruby 
> <http://www.railsonmaui.com/blog/2014/10/22/enums-and-queries-in-rails-4-dot-1/>
>
> At the bottom of the article, I post my recommendation:
>
>
> Recommendations to the Rails Core Team
>
> In response to this issue, I submitted this github issue: Rails where 
> query should see value is an enum and convert a string #17226 
> <https://github.com/rails/rails/issues/17226>
>
>    1. @Bounga and @rafaelfranca on Github suggest that we can’t 
>    automatically convert enum string values in queries. I think that is true 
>    for converting cases of a ? 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:
>       1. This is the sort of “magic” that I expect from Rails.
>       2. Existing methods 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.*
>    2. Aside from putting automatic conversion of the enum hash 
>    attributes, I recommend we change the automatic conversion of Strings to 
>    integers to use the stricter 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 
>    
> <https://github.com/rails/rails/blob/master/activerecord/test/cases/types_test.rb>.
>  
>    For example, this test:
>    
>    1
>    
>    assert_equal 0, type.type_cast_from_user('bad')
>    
>    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.*
>    
>

-- 
You received this message because you are subscribed to the Google Groups "Ruby 
on Rails: Core" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to rubyonrails-core+unsubscr...@googlegroups.com.
To post to this group, send email to rubyonrails-core@googlegroups.com.
Visit this group at http://groups.google.com/group/rubyonrails-core.
For more options, visit https://groups.google.com/d/optout.

Reply via email to