Rails いつも忘れる集 / アソシエーションのあるモデルを含んだフォーム作成
いっつも何かつくる時にググっているもの。
いいかげん記憶したいけど、いつも忘れる…。
関係モデルを含むフォームの作成
has_many や has_one などでアソシエーションがあるモデルを含むフォームを作成したい時。
models/user.rb
accepts_nested_attributes_for
が大事。
ruby
1
2
3
4
class User < ActiveRecord::Base
has_many :phones
accepts_nested_attributes_for :phones
end
controllers/user_controller.rb
phones_attributes
が必須。ないと値が取れない。
ruby
1
2
3
4
5
6
def strong_params
params.require(:user).permit(
:name, :email,
phones_attributes: [:number, :device],
)
end
views/users/new.html.haml
fields_for
でネストされたモデルのフォームをつくる。
haml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
= form_for @user do |f|
= f.label :name
= f.text_field :name
= f.label :email
= f.text_field :email
= f.fields_for :phones, @user.phones.build do |p|
= p.label :number
= p.text_field :number
= p.label :device
= p.text_field :device, options_for_select(["携帯", "自宅"]), prompt: ""
@user.phones.build を直接ビューの中に書いてもいいんだけど、
バリデーションエラーで render 'new'
すると入力した値が消えるので、
コントロール側で @job.type_connections.build
とした方が良いと思う。
もし、has_many ではなく has_one のアソシエーションを使っている場合は、
@user.phones.build
ではなく @user_build_phone
なので注意。
has_many で3個同時にphoneをつくりたいんだって場合は、
コントロール側で
ruby
1
2
3
3.times do
@user.phones.build
end
とすると、自動的に3つ分フィールドが現れる。
updateする時
これで一見、いい感じになったと思いきや、
updateメソッドを実装する時にもちょっとハマる。
何も考えずにやると has_many で関連付けられたデータが沢山できてしまう。
ので、該当するidをコントローラーに渡す必要がある。
controllers/users_controller.rb
:id を許可しておくのを意外と忘れがち。
ruby
1
2
3
4
5
6
def strong_params
params.require(:user).permit(
:name, :email,
phones_attributes: [:id, :number, :device],
)
end
よく忘れるなー。