Rails4.1から導入されたEnum型で、個人的に引っかかったこと
そもそもrailsのenumとは?
rails4.2から導入された、簡単にいうとintegerとstring型を紐付けするものです。
マイグレーションファイルは以下の通りです。
0160225070148_create_people.rb
class CreatePeople < ActiveRecord::Migration
def change
create_table :people do |t|
t.string :name, null: false
t.integer :sex, null: false, limit: 1
t.timestamps null: false
end
end
end
具体的な書き方としては、
person.rb
class Person < ActiveRecord::Base
enum sex: %i( man woman )
end
、、といった具合でこの場合だと0=>man,1=>womanを返す属性名、属性の値が新しく定義されるようになります。
さらに具体的に見ていきます。 コマンドラインで
command
$ bundle exec rails console
$ me = Person.new
$ me.sex = 1
$ me.sex
=> "woman"
と、言うようにハッシュでintegerとstringを扱うことができるようになりました。
また他にも便利なメゾットがあります。
command
$ me.man!
=> "man"
$ me.sex
=> "man"
$ me.woman?
=> "false"
$ me.man?
=> "true"
本題に入っていきます。
form_forでenum型を扱うときに引っかかってしまったこと(ー ー;)
_form.html.haml
= form_for @person, url:url, html: {role: 'form', class: "form-horizontal"} do |f|
....
.form-group
= f.label :sex, class: "control-label"
= f.number_field :sex, class: "form-control"
enumを使ったので、今回の場合は0か1を入力しなければなりません。 従ってnumber_fieldを使ってformを実装しようとしたのですが、、、
error
'1'is not a valid sex
とでてきてしまい、うまくいかない、、、
原因は簡単です。formはデフォルトで""がついてしまっているためたとえnumber_fieldで1と打ってもrailsでは'1'と解釈されてしまうからです。
#enumを使っていなかったらうまくいきます。なぜenumを使ったらうまくいかないのかわからないですm(_ _)m
しかしsexはintegerがデータ型なので、どうしようか、、、
解決策
_form.html.haml
.form-group
= f.label :sex, class: "control-label"
= f.select :sex, Person.sexes.keys class: "form-control"
と言った具合にselectタグでmanとwomanを選択させるという方法をとることで、enumのエラーを治すことができました。