セレクトボックスをrailsのviewで書くにはcollection_select
ヘルパーメッソドを
利用すると思います。
そこで下記のような実装をしていました。
controller#action
def new
@staff_member = StaffMember.new
@staff_roles = Role.select(:id, :role_name).order(id: :asc)
end
view(一部抜粋)
<div class="form-group">
<%= f.label :role_id, '権限', class: 'col-sm-3 control-label' %>
<div class="col-sm-6 col-md-6 col-lg-6">
<%= f.collection_select(
:role_id, @staff_roles, :id, :role_name,
{prompt: "選択してください"}, {class: 'form-control'}) %>
</div>
</div>
この実装で問題なく動いていたのですが、modelに下記のvalidationを実装してから
挙動が変わりました。
model(一部抜粋)
validates :family_name, :given_name, presence: true
このようにvalidatesを指定したカラムは、select対象のカラムであるrole_idとは
別のfamily_nameで、一見何の関連もないように見えます。
ところがこの実装後、ブラウザ上でfamily_nameにデータ入れてcreateすれば
問題なくデータベースにsaveされますが、family_nameをブランクしてvalidation errorを
起こそうとすると下記のエラーになってしまいます。
ActionView::Template::Error (undefined method `map' for nil:NilClass):
28: <div class="form-group">
29: <%= f.label :role_id, '権限', class: 'col-sm-3 control-label' %>
30: <div class="col-sm-6 col-md-6 col-lg-6">
31: <%= f.collection_select(
32: :role_id, @staff_roles, :id, :role_name,
33: {prompt: "選択してください"}, {class: 'form-control'}) %>
34: </div>
family_nameとは無関係なcollection_selectについて何やら言っているようです。
理由は調べていませんが、collection_selectの引数である**@staff_roles**
モデルオブジェクトをアクションで受け取るのやめ、viewに直接書いたら改善されました。
controller#action(修正後)
def new
@staff_member = StaffMember.new
end
view(修正後)
<div class="form-group">
<%= f.label :role_id, '権限', class: 'col-sm-3 control-label' %>
<div class="col-sm-6 col-md-6 col-lg-6">
<%= f.collection_select(
:role_id, Role.all, :id, :role_name,
{prompt: "選択してください"}, {class: 'form-control'}) %>
</div>
</div>