Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
3
Help us understand the problem. What is going on with this article?
@suketa

Rails6 のちょい足しな新機能を試す44(enum 編)

More than 1 year has passed since last update.

はじめに

Rails 6 に追加されそうな新機能を試す第44段。 今回は、 enum 編です。
Rails 6 では、 enum で指定する値が、Hash, シンボルの配列、文字列の配列以外の場合は、 ArgumentError が発生するようになりました。
わかりにくいバグを防ぐのが目的です。

Ruby 2.6.3, Rails 6.0.0.rc1, Rails 5.2.3 で確認しました。Rails 6.0.0.rc1 は gem install rails --prerelease でインストールできます。

$ rails --version
Rails 6.0.0.rc1

プロジェクトを作る

bin/rails new rails6_0_0rc1

モデルを作る

bin/rails g model Child name generation:integer

Child モデルに enum を追加する

ここで、わざとバグになる紛らわしい enum を設定します。

app/models/child.rb
class Child < ApplicationRecord
  enum generation: [baby: 0, toddler: 1, preschool: 2, gradeschool: 3, teen: 4, young_adult: 5]
end

rake db:migrate を実行する

$ bin/rake db:create db:migrate

Rails 6 では

rails consoleChild のインスタンスを作ろうとすると ArgumentError が発生します。

$ bin/rails c
...
irb(main):001:0> c = Child.new
Traceback (most recent call last):
        3: from (irb):1
        2: from app/models/child.rb:1:in `<main>'
        1: from app/models/child.rb:2:in `<class:Child>'
ArgumentError (Enum values [{:baby=>0, :toddler=>1, :preschool=>2, :gradeschool=>3, :teen=>4, :young_adult=>5}] must be either a hash, an array of symbols, or an array of strings.)

Rails 5 では

ArgumentError が発生しませんが、 generation に :baby を設定しようとするとエラーになります。

$ bin/rails c
irb(main):001:0> child = Child.new
=> #<Child id: nil, name: nil, generation: nil, created_at: nil, updated_at: nil>
irb(main):002:0> child.generation = :baby
Traceback (most recent call last):
        1: from (irb):2
ArgumentError ('baby' is not a valid generation)

Child.generations で調べてみると設定できるのは、{ baby: 0, toddler: 1, preschool: 2, gradeschool: 3, teen: 4, young_adult: 5 } だけとわかります。
enum で指定したのは、1つの Hash オブジェクトを要素とする配列になってしまっているためです。

irb(main):003:0> Child.generations
=> {{:baby=>0, :toddler=>1, :preschool=>2, :gradeschool=>3, :teen=>4, :young_adult=>5}=>0}

意図した動作にするには

以下のように [] で囲まないで、 {} で囲めば、意図した通りの動作になります。

app/models/child.rb
class Child < ApplicationRecord
  enum generation: { baby: 0, toddler: 1, preschool: 2, gradeschool: 3, teen: 4, young_adult: 5 }
end

試したソース

試したソースは以下にあります。
https://github.com/suketa/rails6_0_0rc1/tree/try044_enum_validation

参考情報

3
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
suketa
Rails初心者なRubyコミッター
ruby-dev
Ruby開発はRuby on Railsをコア技術とし、Web系から基幹系まで多様な開発に携わっています。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
3
Help us understand the problem. What is going on with this article?