2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Posted at

はじめに

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

参考情報

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?